1 À rendre (livrables)


2 Objectifs

Ce carnet de notes a pour but de

3 Données des tables de mortalité

Les tables de données de vie ont été téléchargées à partir de https://www.mortality.org. Elles ont été élaborées pour vous et peuvent être téléchargées à partir de l’URL ‘https://www.dropbox.com/s/tnci38tqchxwic6/full_life_table.Rds?dl=0’, enregistrées dans votre répertoire de travail.

Si vous installez et chargez le paquet https://cran.r-project.org/web/packages/demography/index.html, vous trouverez également des tables de mortalité.

Nous étudions des tables de mortalité décrivant des pays d’Europe occidentale (France, Grande-Bretagne -en fait Angleterre et Pays de Galles-, Italie, Pays-Bas, Espagne et Suède) et les États-Unis.

Nous chargeons les tables de mortalité annuelles pour les femmes, les hommes et la population totale (both) des différents pays.

Téléchargez les données depuis https://www.dropbox.com/s/tnci38tqchxwic6/full_life_table.Rds?dl=0 dans votre répertoire de travail (working directory). Enregistrez-les sous le nom de full_life_table.Rds. Chargez-le en mémoire en utilisant readr::read_rds().

fpath <- 'full_life_table.Rds'  # once you have downloaded the file

if (! file.exists(fpath)){
  cat(glue('{fpath} should be in working directory!'))
} else {
  life_table <- readr::read_rds(fpath)
  glimpse(life_table)
}

Rows: 379,170 Columns: 12 $ Year 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816,~ $ Age 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2~ $ mx 0.20534, 0.04669, 0.03412, 0.02304, 0.01604, 0.01373, 0.01186, 0.01016,~ $ qx 0.17972, 0.04562, 0.03355, 0.02277, 0.01591, 0.01364, 0.01179, 0.01011,~ $ ax 0.31, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50,~ $ lx 100000, 82028, 78285, 75659, 73936, 72760, 71768, 70921, 70204, 69601, ~ $ dx 17972, 3742, 2626, 1723, 1176, 992, 846, 717, 604, 509, 423, 362, 325, ~ $ Lx 87524, 80156, 76972, 74798, 73348, 72264, 71344, 70563, 69902, 69346, 6~ $ Tx 4009912, 3922388, 3842232, 3765260, 3690462, 3617114, 3544850, 3473506,~ $ ex 40.10, 47.82, 49.08, 49.77, 49.91, 49.71, 49.39, 48.98, 48.47, 47.89, 4~ $ Country “France”, “France”, “France”, “France”, “France”, “France”, “France”, “~ $ Gender ”Both“,”Both“,”Both“,”Both“,”Both“,”Both“,”Both“,”Both“,”Both",~

Vérifiez sur http://www.mortality.org la signification des différentes colonnes:

Le document Tables de mortalité françaises pour les XIXe et XXe siècles et projections pour le XXIe siècle contient des informations détaillées sur la construction des Tables de mortalité pour la France. On peut en général distinguer deux types de Tables de mortalité : les Tables du moment qui contiennent pour chaque année civile, les risques de mortalité à différents âges pour cette même année ; et les Tables de génération qui contiennent pour une année de naissance donnée, les risques de mortalité auxquels un individu né au cours de cette année a été exposé.

Les tables de mortalité étudiées dans ce travail sont les Tables du moment. D’après le document de Vallin et Meslé, l’élaboration des tables de mortalité a nécessité des choix et un travail substantiel d’édition.

Voir (entre autres)

Voir aussi les [schémas de Lexis] (https://en.wikipedia.org/wiki/Lexis_diagram).


À partir de maintenant, la table universelle est nommée life_table.

Les tables de mortalité sur lesquelles vous allez travailler sont appelées tableaux de mortalité de l’année.

Nom de la colonne Type de colonne Signification
Année nombre entier
Age entier Âge \(x\)
mx double Taux de mortalité central à l’âge \(x\) : \(m_x\)
qx double Probabilité de mourir entre l’âge de \(x\) et l’âge de \(x+1\) \(q_x = \frac{m_x}{1+ m_x/2}\)
lx entier Nombre de personnes encore en vie à l’âge de \(x\) dans une cohorte fictive de \(100000\)
dx integer Nombre de personnes décédées entre l’âge \(x\) et \(x+1\) durant l’année dans la cohorte fictive
Lx entier Nombre d’années-personnes vécues entre l’âge de \(x\) et \(x+1\), \(L_x = \ell_x - d_x\times a_x\) dans la cohorte fictive
Tx entier
ex double Espérance de vie résiduelle à l’âge \(x\)
Pays facteur Pays-Bas/…
Sexe facteur Féminin / Masculin

Voir Preston et al. pour les détails et les explications.

4 L’Ouest (de l’Europe) en 1948

On observe, pour l’année 1948, que le quotient de mortalité commence à un niveau élevé puis diminue jusqu’à l’âge de l’adolescence avant d’entreprendre une croissance monotone. Le graphe suit la même tendance quel que soit le pays. Cependant, il diffère selon le sexe. On peut observer un quotient de mortalité légèrement plus élevé chez les hommes.

Sur ce plotly on peut constater que durant l’année 1948, l’Espagne et l’Italie possédaient un taux de mortalité bien supérieur à celui des États-Unis et du reste de l’Europe. Ce rapport s’équilibre à l’âge de 40. On voit également que la courbe des femmes est supérieure à celle des hommes. Les autres pays quant à eux sont comparables au taux des USA.

5 Evolution des taux de mortalité depuis la seconde guerre mondiale

Warning: Transformation introduced infinite values in continuous y-axis

et qui renvoie un tableau de données avec le schéma :

Nom de la colonne Type de colonne
Année entier
Age entier
qx double
qx.ref_year double
Pays facteur
Sexe Facteur

(Pays, Année, Age, Sexe) sert de clé primaire, qx désigne le quotient de mortalité à Age pour Année et Genre dans Pays tandis que qx_ref_year indique le quotient de mortalité à Age pour l’argument reference_year. dans le pays pour le sexe.

ratio_mortality_rates <- function(df,reference_year, target_year){
  life_table_target_y <- df[df$Year %in% target_year,]
  life_table_1 <- select(life_table_target_y,Year,Age,qx,ex,Country,Gender)
  names(life_table_1) <- c('Year','Age','qx','qx.ref_year','Country','Gender')
  life_table_ref_year <-df[(df$Year==reference_year),]
  life_table_ref_year <- select(life_table_ref_year,Year,Age,qx,Country,Gender)
  for(i in 1: nrow(life_table_1)){
    if(life_table_1[i,1]==reference_year){
      life_table_1[i,4] <- life_table_1[i,3]
    }
    else {
        life_table_2 <- life_table_ref_year[(life_table_ref_year$Age==as.numeric(life_table_1[i,2])) & (life_table_ref_year$Country==as.character(life_table_1[i,5])) & life_table_ref_year$Gender==as.character(life_table_1[i,6]),]
      life_table_1[i,4] <- life_table_2[1,3]
    }
  }
  return (life_table_1)
}

life_table_1<- ratio_mortality_rates(life_table,1946,seq(1946,2016,10))
head(life_table_1)
Warning: Transformation introduced infinite values in continuous y-axis

Au fil du temps, on peut voir que la courbe du ratio des quotients est de plus en plus basse par rapport aux années précédentes. On peut conclure que le quotient de mortalité diminue avec les années, ce qui pourrait s’expliquer par l’amélioration des conditions de vie. De plus, on peut remarquer que les ratios des quotients de mortalité des hommes sont légèrement au-dessus des femmes.

6 Tendances

Warning: Transformation introduced infinite values in continuous y-axis

Ce facette témoigne de l’évolution de la mortalité infantile au cours du temps pour les âges 0,1 et 5. Comme vu précédemment, on remarque une diminution du taux de mortalité au fil des années.De plus, la courbe des hommes est presque identique à celle des femmes.

Intéressons-nous à présent aux âges 15-20-40-60. On peut observer, une fois de plus, la diminution du taux de mortalité au travers des années. Cependant, les 2 guerres mondiales entraînent des pics sur les courbes (1914-1918, 1939-1945), en particulier chez les hommes de 15-20 ans.

7 Réarrangement

Vous pouvez utiliser les fonctions pivot_wider, pivot_longer du package tidyr::.

Le schéma du résultat devrait avoir l’aspect suivant:

Nom de colonne Type
Country factor
Gender factor
Year integer
0 double
1 double
2 double
3 double
\(\vdots\) \(\vdots\)

8 Espérance de vie

esp_res <- function(v_qx,age){
  
  sum = 0
  for ( i in age : 109){
    pro = 1
    for (j in age : i){
      m = v_qx[j]/(1-(v_qx[j]/2))
      pro = pro * (1-m)
    }
    sum = sum + pro
  }
  return(as.numeric(sum))
}
tab_esp_res <- function(df){
  df %>%
    select(Country,Gender,Year,Age,qx) %>%
    pivot_wider(names_from = Age, values_from = qx) -> df
  for(i in 1:nrow(df)){
    v_qx <- df[i,4:113]
    v_qx <- as.numeric(v_qx)
    
    for(j in 4:113){
      df[i,j] = esp_res(v_qx,j-3)
    }
  }
  df = pivot_longer(df,cols = -c(Country,Gender,Year), names_to = "Age", values_to ="Res_lex")
  return(df)
}

life_table_res_lex <- tab_esp_res(life_table)
head(life_table_res_lex)
Warning: Ignoring unknown aesthetics: Group

9 PCA et SVD sur les tables de log-mortalité

Warning: ggrepel: 107 unlabeled data points (too many overlaps). Consider increasing max.overlaps

Warning: ggrepel: 13 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 104 unlabeled data points (too many overlaps). Consider increasing max.overlaps

Warning: ggrepel: 7 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 103 unlabeled data points (too many overlaps). Consider increasing max.overlaps

Warning: ggrepel: 63 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 108 unlabeled data points (too many overlaps). Consider increasing max.overlaps

Warning: ggrepel: 36 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 102 unlabeled data points (too many overlaps). Consider increasing max.overlaps

On peut constater que dans tous les screeplots, la première composante principale explique plus de 93 % de la variance. Pour l’ACP centrée et réduite, il faut garder les 2 premières composantes principales, car elles représentent 96.2 % de la variance expliquée. Ensuite, pour le cas d’une ACP centrée et non réduite, il faut également garder les 2 premières composantes principales, car elles représentent 96.5 % de la variance expliquée.Enfin, pour les ACP non centrée et réduite et non centrée et non réduite, on ne garde que la première composante, car elle représente dans les deux cas 99.9 % de la variance expliquée. Autrement dit, 99.9 % de l’information (variance) est contenue dans les données de la première composante principale.

Sur les deux premiers cercles de corrélation (centré réduit, centré non réduit) on remarque que les variables 0,1,…,109, qui correspondent aux âges sont corrélées négativement à la première composante principale et sont corrélées entre elles. De plus, on constate qu’elles sont très proches du cercle de corrélations donc elles sont bien représentées. Concernant les 2 derniers cercles de corrélations(non centré et réduit, non centré et non réduit), les flèches sont de longueur supérieure à 1, ce qui est normal, car les données ne sont pas centrées. De plus, on remarque sur ces deux cercles que les âges sont corrélés sur les deux composantes principales.

Tout d’abord, les individus correspondent dans notre étude aux années et les variables 0,1,…,109 correspondent aux âges. Un individu qui se trouve du même côté d’une variable donnée a une valeur élevée pour cette variable et un individu qui se trouve dans le côté opposé d’une variable donnée a une faible valeur pour cette variable.

Dans les 2 premiers biplots, on constate que pratiquement la moitié des individus se trouvent du même côté que ceux des variables. Tandis que dans le dernier biplot, tous les individus se trouvent du coté opposé à ceux des variables. Puis, sur le biplot de l’ACP non centrée et réduite, on ne voit plus les individus.

Les bâtons sont proportionnels aux carrés des valeurs singulières normalisées par la somme des carrés des valeurs singulières. Si l’on ne centre pas nos données, nos données seront trop réduites, il faut alors les centrer. En effet, pour la première composante principale, les bâtons rose et vert représentent pratiquement 100 % et plus de 85 % de la part de l’inertie totale expliquée par la première composante. On peut alors projeter nos données sur une dimension et on perdra très peu d’information. Cependant, en faisant cela, nous réduisons beaucoup trop nos données.

On constate que si l’on centre et que l’on normalise ou non nos données, on récupère pratiquement 75 % d’informations sur la première composante principale et on récupère également des informations sur la seconde composante principale.

Il faut donc obligatoirement centrer nos données, quant à la normalisation, elle reste optionnelle.

10 Modèle Lee-Carter pour la mortalité aux États-Unis

Au cours du siècle dernier, aux États-Unis et en Europe occidentale, les quotients de mortalité à tous les âges ont présenté une tendance générale à la baisse. Cette tendance à la baisse n’a pas toujours été homogène entre les âges.

Le modèle de Lee-Carter a été conçu pour modéliser et prévoir l’évolution du quotient log-mortalité. l’évolution des quotients de mortalité logarithmique pour les États-Unis au cours du XXe siècle.

Soit \(A_{x,t}\) le logarithme du quotient de mortalité à l’âge \(x\) pendant l’année \(t\in T\). pour une population donnée (définie par le sexe et le pays).

Le modèle de Lee-Carter suppose que les quotients de mortalité logarithmiques observés sont échantillonnés selon le modèle suivant \[ A_{x,t} \sim_{\text{indépendant}} a_x + b_x \kappa_t + \epsilon_{x,t} \]\((a_x)_x, (b_x)_x\) et \((\kappa_t)_t\) sont des vecteurs inconnus qui satisfont \[ a_x = \frac{1}{|T|}\sum_{t \in T} A_{x,t}\qquad \sum_{t\in T} \kappa_t = 0 \qquad \sum_{x} b_x^2 =1 \] et \(\epsilon_{x,t}\) sont des variables aléatoires i.i.d. gaussiennes.

10.1 Données US

  • Ajustez un modèle Lee-Carter sur les données américaines (pour les données masculines et féminines) en vous entraînant sur les années 1933 jusqu’à 1995.
  • Comparez l’ajustement fourni par le modèle de Lee-Carter avec l’ajustement fourni par un modèle SVD tronqué de rang \(2\).
  • Comparez les vecteurs avec \((a_x)_x, (b_x)_x\) et \((\kappa_t)_t\) avec les vecteurs singuliers appropriés.
  • Utilisez le modèle de Lee-Carter pour prédire les quotients de mortalité pour les années 2000$ à 2015$.
  • Tracez les prédictions et les observations pour les années 2000, 2005, 2010 et 2015.

10.2 Application du modèle de Lee-Carter à un pays européen

  • Ajustez un modèle de Lee-Carter à un pays européen.
  • Commentaire
  • Comparez avec la SVD tronquée de rang 2.
  • Utiliser le modèle de Lee-Carter pour prédire les quotients de mortalité pour les années \(2000\) à \(2015\).
  • Commentaire

Le coefficient de mortalité de la france semble en moyenne aligné avec le coefficient de mortalité obtenu par le regréssement linéaire. En effet, ce dernier est un prolongement du coefficient de mortalité 1933 à 1995.

Tracez les prédictions et les observations pour les années \(2000, 2005, 2010, 2015\).

10.3 Prédictions de l’espérance de vie à différents âges

  • Utiliser l’approximation de Lee-Carter pour estimer les espérances de vie résiduelles.
  • Comparer avec les espérances de vie résiduelles observées

11 Références

Tables de mortalité et démographie

Graphiques et rapports

Tidyverse

PCA, SVD

Démographie

LS0tDQp0aXRsZTogJ1Byb2pldCAyMDIxOiBEw6ljb21wb3NpdGlvbiBlbiB2YWxldXJzIHNpbmd1bGnDqHJlcyBldCBUYWJsZXMgZGUgbW9ydGFsaXTDqScNCmF1dGhvcjogIkJvdWxhbmdlciwgTmFudGhha3VtYXIgZXQgQmFpIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9mb2xkaW5nOiBub25lDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2M6IHllcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCnN1YnRpdGxlOiAnw4ljaMOpYW5jZTogMjAyMS0xMi0wOScNCnBhcmFtczoNCiAgZGF0YXBhdGg6IGh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3MvdG5jaTM4dHFjaHh3aWM2L2Z1bGxfbGlmZV90YWJsZS5SZHM/ZGw9MA0KICBjb3VudHJ5X2NvZGU6IGZyX3QNCiAgY291bnRyeTogRnJhbmNlDQogIHRpbWVjb3Vyc2U6IDE5NDU6MjAxNQ0KICBsYW5ndWFnZTogRnJlbmNoDQotLS0NCg0KIyDDgCByZW5kcmUgKGxpdnJhYmxlcykNCg0KLSAqKjIwMjEtMTItMDk6KiogdW4gZmljaGllciBgbm9tMV9ub20yLlJtZGAgcXVpIHBldXQgw6p0cmUgYHRyaWNvdMOpYCAoa25pdHRlZCkgc291cyBgcnN0dWRpb2AuDQogIC0gVm90cmUgZmljaGllciBkb2l0IMOqdHJlIHRyaWNvdMOpIHNhbnMgZXJyZXVycyBldCBsZSByw6lzdWx0YXQgZG9pdCDDqnRyZSB1biBkb2N1bWVudCBgaHRtbGAgcXVpIHBldXQgw6p0cmUgdmlzdWFsaXPDqSBkYW5zIHVuIG5hdmlnYXRldXIgbW9kZXJuZS4NCiAgLSBMZSBmaWNoaWVyIGRvaXQgY29udGVuaXIgbGUgY29kZSB1dGlsaXPDqSBwb3VyIGNvbnN0cnVpcmUgbGVzIGdyYXBoaXF1ZXMgZXQgbGVzIHLDqXN1bcOpcyBudW3DqXJpcXVlcy4NCiAgLSBMZSBmaWNoaWVyIGRvaXQgY29udGVuaXIgbGUgdGV4dGUgZGUgdm9zIGNvbW1lbnRhaXJlcyAoZW4gYW5nbGFpcyBvdSBlbiBmcmFuw6dhaXMpLg0KICAtIExlcyBjb21tZW50YWlyZXMgZG9pdmVudCDDqnRyZSByw6lkaWfDqXMgYXZlYyBzb2luIGV0IHByw6ljaXNpb24gZXQgZG9pdmVudCDDqnRyZSBjb25jaXMuDQogIC0gTGUgZmljaGllciBgbm9tMV9ub20yLlJtZGAgc2VyYSB0w6lsw6ljaGFyZ8OpIHN1ciBgTW9vZGxlYC4NCi0gKioyMDIxLTEyLTE0OioqIHVuZSBwcsOpc2VudGF0aW9uIG9yYWxlIGRlIDIwIG1pbnV0ZXMgc3VyIGRlcyDDqWzDqW1lbnRzIGV4dHJhaXRzIGRlIHZvdHJlIHByZW1pZXIgbGl2cmFibGUgYG5vbTFfbm9tMi5SbWRgLg0KICAtIExhIHByw6lzZW50YXRpb24gY29uc2lzdGUgZW4gdW4gZXhwb3PDqSBkZSAxMiBtaW51dGVzIGV0IDggbWludXRlcyBkZSBxdWVzdGlvbnMgZXQgcsOpcG9uc2VzLg0KICAtIExhIHByw6lzZW50YXRpb24gZXN0IHNvdXRlbnVlIHBhciBkZXMgZGlhcG9zaXRpdmVzDQogIC0gTGVzIGRpYXBvc2l0aXZlcyBnw6luw6lyw6llcyDDoCBwYXJ0aXIgZGUgYFJtYXJrZG93bmAgZG9pdmVudCDDqnRyZSBwcml2aWzDqWdpw6llcy4gVm91cyBwb3V2ZXogY2hvaXNpciBsZSBmb3JtYXQgcXVlIHZvdXMgcHLDqWbDqXJleiAoYGJpbmJgLCBgeGFyaW5nYW5gLCBgc2xpZHlgLCBgaW9zbGlkZXNgLCAuLi4pDQoNCi0tLQ0KDQojIE9iamVjdGlmcw0KDQpDZSBjYXJuZXQgZGUgbm90ZXMgYSBwb3VyIGJ1dCBkZQ0KDQogIC0gdHJhdmFpbGxlciBhdmVjIGRlcyAqKnRhYmxlcyoqIChgZGF0YS5mcmFtZXNgLCBgdGliYmxlc2AsIGBkYXRhLnRhYmxlc2AsIC4uLikgZW4gdXRpbGlzYW50IGBkcGx5cmAgb3UgdG91dCBhdXRyZSBsYW5nYWdlIGQnaW50ZXJyb2dhdGlvbiAodGVsIHF1ZSBmb3VybmkgcGFyIGV4ZW1wbGUgcGFyIGBkYXRhLnRhYmxlYCkNCiAgLSB2aXN1YWxpc2VyIGRlcyBkb25uw6llcyBkw6ltb2dyYXBoaXF1ZXMgY29tbWUgY2VsbGVzIGZvdXJuaWVzIHBhciBbSHVtYW4gTW9ydGFsaXR5IERhdGFiYXNlIG9yZ2FuaXphdGlvbl0gKGh0dHBzOi8vd3d3Lm1vcnRhbGl0eS5vcmcpLg0KICAtIGwndXRpbGlzYXRpb24gZGUgbCcqKkFDUCoqIGV0IGQnYXV0cmVzIG3DqXRob2RlcyBtYXRyaWNpZWxsZXMgcG91ciBleHBsb3JlciBkZXMgZW5zZW1ibGVzIGRlIGRvbm7DqWVzIG11bHRpdmFyacOpZXMgKGxlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSBwZXV2ZW50IMOqdHJlIGNvbnNpZMOpcsOpZXMgY29tbWUgZGVzIGVuc2VtYmxlcyBkZSBkb25uw6llcyBtdWx0aXZhcmnDqWVzKS4NCg0KIyBEb25uw6llcyBkZXMgdGFibGVzIGRlIG1vcnRhbGl0w6kgDQoNCkxlcyB0YWJsZXMgZGUgZG9ubsOpZXMgZGUgdmllIG9udCDDqXTDqSB0w6lsw6ljaGFyZ8OpZXMgw6AgcGFydGlyIGRlIFtodHRwczovL3d3dy5tb3J0YWxpdHkub3JnXShodHRwczovL3d3dy5tb3J0YWxpdHkub3JnKS4gRWxsZXMgb250IMOpdMOpIMOpbGFib3LDqWVzIHBvdXIgdm91cyBldCBwZXV2ZW50IMOqdHJlIHTDqWzDqWNoYXJnw6llcyDDoCBwYXJ0aXIgZGUgbCdVUkwgJ2h0dHBzOi8vd3d3LmRyb3Bib3guY29tL3MvdG5jaTM4dHFjaHh3aWM2L2Z1bGxfbGlmZV90YWJsZS5SZHM/ZGw9MCcsIGVucmVnaXN0csOpZXMgZGFucyB2b3RyZSByw6lwZXJ0b2lyZSBkZSB0cmF2YWlsLg0KDQpTaSB2b3VzIGluc3RhbGxleiBldCBjaGFyZ2V6IGxlIHBhcXVldCBbaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2RlbW9ncmFwaHkvaW5kZXguaHRtbF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2RlbW9ncmFwaHkvaW5kZXguaHRtbCksIHZvdXMgdHJvdXZlcmV6IMOpZ2FsZW1lbnQgZGVzIHRhYmxlcyBkZSBtb3J0YWxpdMOpLg0KDQpOb3VzIMOpdHVkaW9ucyBkZXMgdGFibGVzIGRlIG1vcnRhbGl0w6kgZMOpY3JpdmFudCBkZXMgcGF5cyBkJ0V1cm9wZSBvY2NpZGVudGFsZSAoRnJhbmNlLCBHcmFuZGUtQnJldGFnbmUgLWVuIGZhaXQgQW5nbGV0ZXJyZSBldCBQYXlzIGRlIEdhbGxlcy0sIEl0YWxpZSwgUGF5cy1CYXMsIEVzcGFnbmUgZXQgU3XDqGRlKSBldCBsZXMgw4l0YXRzLVVuaXMuDQoNCk5vdXMgY2hhcmdlb25zIGxlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSBhbm51ZWxsZXMgcG91ciBsZXMgZmVtbWVzLCBsZXMgaG9tbWVzIGV0IGxhIHBvcHVsYXRpb24gdG90YWxlIChgYm90aGApIGRlcyBkaWZmw6lyZW50cyBwYXlzLg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQ0KIyBmb3IgZGVidWdnaW5nDQojIHBhcmFtcyBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZnJvbSBZQU1MIGhlYWRlcg0KcGFyYW1zPC0gbGlzdCgNCiAgICB0aW1lY291cnNlPSAxOTQ1OjIwMTUsDQogICAgZGF0YXBhdGg9ICdodHRwczovL3d3dy5kcm9wYm94LmNvbS9zL3RuY2kzOHRxY2h4d2ljNi9mdWxsX2xpZmVfdGFibGUuUmRzP2RsPTAnLA0KICAgIGNvdW50cnlfY29kZT0gJ2ZyX3QnLA0KICAgIGNvdW50cnk9ICdGcmFuY2UnKQ0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KdGltZWNvdXJzZSA8LSBldmFsKHJsYW5nOjpwYXJzZV9leHByKHBhcmFtcyR0aW1lY291cnNlKSkNCmBgYA0KDQpgYGB7ciB0aWR5dmVyc2UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQppZighICdwYWNtYW4nICVpbiUgaW5zdGFsbGVkLnBhY2thZ2VzKClbLDFdKXsNCiAgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCn0NCg0KcGFjbWFuOjpwX2xvYWQodGlkeXZlcnNlKQ0KcGFjbWFuOjpwX2xvYWQocGxvdGx5KQ0KcGFjbWFuOjpwX2xvYWQoZm9yZWFjaCkNCnBhY21hbjo6cF9sb2FkKGl0ZXJhdG9ycykNCnBhY21hbjo6cF9sb2FkKERUKQ0KcGFjbWFuOjpwX2xvYWQoYWRlNCkNCnBhY21hbjo6cF9sb2FkKEZhY3RvTWluZVIpDQpwYWNtYW46OnBfbG9hZChmYWN0b2V4dHJhKQ0KcGFjbWFuOjpwX2xvYWQoRmFjdG9JbnZlc3RpZ2F0ZSkNCnBhY21hbjo6cF9sb2FkKGdnZm9ydGlmeSkNCnBhY21hbjo6cF9sb2FkKHBhdGhsaWJyKQ0KcGFjbWFuOjpwX2xvYWQoZGVtb2dyYXBoeSkNCnBhY21hbjo6cF9sb2FkKGdsdWUpDQoNCmxpYnJhcnkocHVycnIpDQpsaWJyYXJ5KGJyb29tKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShzY2FsZXMpDQpgYGANCg0KYGBge3Igc2V0X2tuaXRyLCBlY2hvPUZBTFNFfQ0Kb2xkX3RoZW1lIDwtdGhlbWVfc2V0KHRoZW1lX2RhcmsoYmFzZV9zaXplPTksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlX2ZhbWlseSA9ICJIZWx2ZXRpY2EiKSkNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGV2YWw9VFJVRSwNCiAgZWNobz1GQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KICBtZXNzYWdlID0gRkFMU0UsDQogIGNhY2hlID0gVFJVRSwNCiAgYXV0b2RlcCA9IFRSVUUsDQogIHRpZHkgPSBGQUxTRSkNCg0KYGBgDQoNCg0KYGBge3Igc2V0dXBfaXNvX2NvZGVzLCBlY2hvPUZBTFNFfQ0KY291bnRyeV9jb2RlIDwtIGxpc3QoZnJfdD0nRlJBVE5QJywNCiAgICAgICAgICAgICAgICAgICAgIGZyX2M9J0ZSQUNOUCcsDQogICAgICAgICAgICAgICAgICAgICBiZT0nQkVMJywNCiAgICAgICAgICAgICAgICAgICAgIGdiX3Q9J0dCUlRFTlcnLA0KICAgICAgICAgICAgICAgICAgICAgZ2JfYz0nR0JSQ0VOVycsDQogICAgICAgICAgICAgICAgICAgICBubD0nTkxEJywNCiAgICAgICAgICAgICAgICAgICAgIGl0PSdJVEEnLA0KICAgICAgICAgICAgICAgICAgICAgc3dlPSdTV0UnLA0KICAgICAgICAgICAgICAgICAgICAgc3A9J0VTUCcsDQogICAgICAgICAgICAgICAgICAgICB1cz0nVVNBJykNCg0KY291bnRyaWVzIDwtIGMoJ2ZyX3QnLCAgJ2diX3QnLCAgJ25sJywgJ2l0JywgJ3NwJywgJ3N3ZScsICd1cycpDQoNCmNvdW50cnlfbmFtZXMgPC0gbGlzdChmcl90PSdGcmFuY2UnLCAgICAgIyB0b3RhbCBwb3B1bGF0aW9uDQogICAgICAgICAgICAgICAgICAgICBmcl9jPSdGcmFuY2UnLCAgICAgICMgY2l2aWxpYW4gcG9wdWxhdGlvbg0KICAgICAgICAgICAgICAgICAgICAgYmU9J0JlbGdpdW0nLA0KICAgICAgICAgICAgICAgICAgICAgZ2JfdD0nRW5nbGFuZCAmIFdhbGVzJywgICAgIyB0b3RhbCBwb3B1bGF0aW9uDQogICAgICAgICAgICAgICAgICAgICBnYl9jPSdFbmdsYW5kICYgV2FsZXMnLCAgICAjIGNpdmlsaWFuIHBvcHVsYXRpb24NCiAgICAgICAgICAgICAgICAgICAgIG5sPSdOZXRoZXJsYW5kcycsDQogICAgICAgICAgICAgICAgICAgICBpdD0nSXRhbHknLA0KICAgICAgICAgICAgICAgICAgICAgc3dlPSdTd2VkZW4nLA0KICAgICAgICAgICAgICAgICAgICAgc3A9J1NwYWluJywNCiAgICAgICAgICAgICAgICAgICAgIHVzPSdVU0EnKQ0KDQpnZW5kZXJfbmFtZXMgPC0gbGlzdCgnYic9J0JvdGgnLA0KICAgICAgICAgICAgICAgICAgICAgJ2YnPSdGZW1hbGUnLA0KICAgICAgICAgICAgICAgICAgICAgJ20nPSdNYWxlJykNCmBgYA0KDQpUw6lsw6ljaGFyZ2V6IGxlcyBkb25uw6llcyBkZXB1aXMgYHIgcGFyYW1zJGRhdGFwYXRoYCBkYW5zIHZvdHJlIHLDqXBlcnRvaXJlIF9kZSB0cmF2YWlsXyAod29ya2luZyBkaXJlY3RvcnkpLiBFbnJlZ2lzdHJlei1sZXMgc291cyBsZSBub20gZGUgYGZ1bGxfbGlmZV90YWJsZS5SZHNgLiBDaGFyZ2V6LWxlIGVuIG3DqW1vaXJlIGVuIHV0aWxpc2FudCBgcmVhZHI6OnJlYWRfcmRzKClgLg0KDQpgYGB7ciBsb2FkX2xpZmVfdGFibGUsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9DQpmcGF0aCA8LSAnZnVsbF9saWZlX3RhYmxlLlJkcycgICMgb25jZSB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBmaWxlDQoNCmlmICghIGZpbGUuZXhpc3RzKGZwYXRoKSl7DQogIGNhdChnbHVlKCd7ZnBhdGh9IHNob3VsZCBiZSBpbiB3b3JraW5nIGRpcmVjdG9yeSEnKSkNCn0gZWxzZSB7DQogIGxpZmVfdGFibGUgPC0gcmVhZHI6OnJlYWRfcmRzKGZwYXRoKQ0KICBnbGltcHNlKGxpZmVfdGFibGUpDQp9DQpgYGANCg0KVsOpcmlmaWV6IHN1ciBbaHR0cDovL3d3dy5tb3J0YWxpdHkub3JnXShodHRwOi8vd3d3Lm1vcnRhbGl0eS5vcmcpIGxhIHNpZ25pZmljYXRpb24gZGVzIGRpZmbDqXJlbnRlcyBjb2xvbm5lczoNCg0KTGUgZG9jdW1lbnQgW1RhYmxlcyBkZSBtb3J0YWxpdMOpIGZyYW7Dp2Fpc2VzIHBvdXIgbGVzIFhJWGUgZXQgWFhlIHNpw6hjbGVzIGV0IHByb2plY3Rpb25zIHBvdXIgbGUgWFhJZSBzacOoY2xlXShodHRwczovL3d3dy5saWZldGFibGUuZGUvZGF0YS9GUkEvRlJBMDAwMDE4MDYxOTk3Q1kxLnBkZikgY29udGllbnQNCmRlcyBpbmZvcm1hdGlvbnMgZMOpdGFpbGzDqWVzIHN1ciBsYSBjb25zdHJ1Y3Rpb24gZGVzIFRhYmxlcyBkZSBtb3J0YWxpdMOpIHBvdXIgbGEgRnJhbmNlLg0KT24gcGV1dCBlbiBnw6luw6lyYWwgZGlzdGluZ3VlciBkZXV4IHR5cGVzIGRlIFRhYmxlcyBkZSBtb3J0YWxpdMOpIDogbGVzICpUYWJsZXMgZHUgbW9tZW50KiBxdWkNCmNvbnRpZW5uZW50IHBvdXIgY2hhcXVlIGFubsOpZSBjaXZpbGUsIGxlcyBfcmlzcXVlc18gZGUgbW9ydGFsaXTDqSDDoCBkaWZmw6lyZW50cyDDomdlcyBwb3VyIGNldHRlIG3Dqm1lIGFubsOpZSA7IGV0IGxlcyAqVGFibGVzIGRlIGfDqW7DqXJhdGlvbiogcXVpIGNvbnRpZW5uZW50IHBvdXIgdW5lIGFubsOpZSBkZSBuYWlzc2FuY2UgZG9ubsOpZSwgbGVzIF9yaXNxdWVzXyBkZSBtb3J0YWxpdMOpIGF1eHF1ZWxzIHVuIGluZGl2aWR1IG7DqSBhdSBjb3VycyBkZSBjZXR0ZSBhbm7DqWUgYSDDqXTDqSBleHBvc8OpLg0KDQoNCkxlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSDDqXR1ZGnDqWVzIGRhbnMgY2UgdHJhdmFpbCBzb250IGxlcyAqVGFibGVzIGR1IG1vbWVudCouIEQnYXByw6hzIGxlIGRvY3VtZW50IGRlIFZhbGxpbiBldCBNZXNsw6ksIGwnw6lsYWJvcmF0aW9uIGRlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSBhIG7DqWNlc3NpdMOpIGRlcyBjaG9peCBldCB1biB0cmF2YWlsIHN1YnN0YW50aWVsIGQnw6lkaXRpb24uDQoNClZvaXIgKGVudHJlIGF1dHJlcykNCg0KLSBwLiAxOSBMZXMgdmFyaWF0aW9ucyBicnV0YWxlcyBkZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgw6AgY2VydGFpbnMgw6JnZXMgcG91ciB1bmUgYW5uw6llIGNpdmlsZSBkb25uw6llDQotIEwnZXN0aW1hdGlvbiBkZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgYXUgZ3JhbmQgw6JnZS4NCg0KVm9pciBhdXNzaSBsZXMgW3NjaMOpbWFzIGRlIExleGlzXSAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV4aXNfZGlhZ3JhbSkuDQoNCg0KDQotLS0NCg0KDQrDgCBwYXJ0aXIgZGUgbWFpbnRlbmFudCwgbGEgdGFibGUgdW5pdmVyc2VsbGUgZXN0IG5vbW3DqWUgYGxpZmVfdGFibGVgLg0KDQpMZXMgdGFibGVzIGRlIG1vcnRhbGl0w6kgc3VyIGxlc3F1ZWxsZXMgdm91cyBhbGxleiB0cmF2YWlsbGVyIHNvbnQgYXBwZWzDqWVzIF90YWJsZWF1eCBkZSBtb3J0YWxpdMOpIGRlIGwnYW5uw6llXy4NCg0KDQoNCnwgTm9tIGRlIGxhIGNvbG9ubmUgfCBUeXBlIGRlIGNvbG9ubmUgfCBTaWduaWZpY2F0aW9uIHwNCnw6LS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS18LS0tLS0tLS0tLXwNCnwgKipBbm7DqWUqKiB8IG5vbWJyZSBlbnRpZXIgfCB8DQp8ICoqQWdlKiogfCBlbnRpZXIgfCDDgmdlICR4JCB8DQp8IG14IHwgZG91YmxlIHwgVGF1eCBkZSBtb3J0YWxpdMOpIGNlbnRyYWwgw6AgbCfDomdlICR4JCA6ICRtX3gkIHwNCnwgX19xeF9fIHwgZG91YmxlIHwgUHJvYmFiaWxpdMOpIGRlIG1vdXJpciBlbnRyZSBsJ8OiZ2UgZGUgJHgkIGV0IGwnw6JnZSBkZSAkeCsxJCAkcV94ID0gXGZyYWN7bV94fXsxKyBtX3gvMn0kIHwgQXggfCBkb3VibGUgfCAkIDUsNSAkLg0KfCBheCB8IGRvdWJsZSB8IDAsNSQgc2F1ZiDDoCBsJ8OiZ2UgMCQgfA0KfCBseCB8IGVudGllciB8IE5vbWJyZSBkZSBwZXJzb25uZXMgZW5jb3JlIGVuIHZpZSDDoCBsJ8OiZ2UgZGUgJHgkIGRhbnMgdW5lIGNvaG9ydGUgZmljdGl2ZSBkZSAkMTAwMDAwJCB8IGR4IHwgZW50aWVyIHwgTm9tYnJlIGRlIHBlcnNvbm5lcyBlbmNvcmUgZW4gdmllIMOgIGwnw6JnZSBkZSAkeCQuDQp8IGR4IHwgaW50ZWdlciB8IE5vbWJyZSBkZSBwZXJzb25uZXMgZMOpY8OpZMOpZXMgZW50cmUgbCfDomdlICR4JCBldCAkeCsxJCBkdXJhbnQgbCdhbm7DqWUgZGFucyBsYSBjb2hvcnRlIGZpY3RpdmUgfA0KfCBMeCB8IGVudGllciB8IE5vbWJyZSBkJ2FubsOpZXMtcGVyc29ubmVzIHbDqWN1ZXMgZW50cmUgbCfDomdlIGRlICR4JCBldCAkeCsxJCwgJExfeCA9IFxlbGxfeCAtIGRfeFx0aW1lcyBhX3gkIGRhbnMgbGEgY29ob3J0ZSBmaWN0aXZlIHwNCnwgVHggfCBlbnRpZXIgfCB8DQp8IGV4IHwgZG91YmxlIHwgRXNww6lyYW5jZSBkZSB2aWUgcsOpc2lkdWVsbGUgw6AgbCfDomdlICR4JCB8DQp8ICoqUGF5cyoqIHwgZmFjdGV1ciB8IFBheXMtQmFzLy4uLiAgICAgICAgfA0KfCAqKlNleGUqKiB8IGZhY3RldXIgfCBGw6ltaW5pbiAvIE1hc2N1bGluIHwgRmVtbWUgLyBIb21tZQ0KDQpWb2lyICBQcmVzdG9uIF9ldCBhbC5fIHBvdXIgbGVzIGTDqXRhaWxzIGV0IGxlcyBleHBsaWNhdGlvbnMuDQoNCg0KDQpgYGB7cn0NCmxpZmVfdGFibGUgPC0gbGlmZV90YWJsZSAlPiUgDQogIGZpbHRlcihHZW5kZXIhPSdCb3RoJykNCmhlYWQobGlmZV90YWJsZSkNCmBgYA0KDQoNCg0KIyBMJ091ZXN0IChkZSBsJ0V1cm9wZSkgZW4gMTk0OA0KDQotIFsgXSBUcmFjZXogbGVzIF9xdW90aWVudHMgZGUgbW9ydGFsaXTDqV8gZGUgdG91cyBsZXMgcGF5cyDDoCB0b3VzIGxlcyDDomdlcyBwb3VyIGwnYW5uw6llIDE5NDguDQoNCmBgYHtyIGZpZy5hc3AgPSAwLjgsIGZpZy53aWR0aCA9IDl9DQpsaWZlX3RhYmxlXzE5NDggPC0gbGlmZV90YWJsZVsobGlmZV90YWJsZSRZZWFyPT0xOTQ4KSxdDQpsaWZlX3RhYmxlXzE5NDggPC0gc2VsZWN0KGxpZmVfdGFibGVfMTk0OCxZZWFyLEFnZSxxeCxDb3VudHJ5LEdlbmRlcikNCiNoZWFkKGxpZmVfdGFibGVfMTk0OCkNCg0KKGdncGxvdChsaWZlX3RhYmxlXzE5NDgpKyBhZXMoeD1BZ2UsIHk9cXgpDQogICtnZW9tX2xpbmUoYWVzKGNvbG9yPUNvdW50cnksIGdyb3VwPUdlbmRlcikpDQogICtsYWJzKHRpdGxlPSdRdW90aWVudCBkZSBtb3J0YWxpdMOpIHBhciBhZ2UnLCB5PSdRdW90aWVudCBkZSBtb3J0YWxpdMOpJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikpDQogICsgZmFjZXRfZ3JpZChDb3VudHJ5fkdlbmRlcikrc2NhbGVfeV9sb2cxMChsYWJlbHM9c2NpZW50aWZpYykNCiAgK3RoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID03MDAsIHdpZHRoPTgwMCkNCmBgYA0KDQotIFsgXSBDb21tZW50YWlyZQ0KDQpPbiBvYnNlcnZlLCBwb3VyIGwnYW5uw6llIDE5NDgsIHF1ZSBsZSBxdW90aWVudCBkZSBtb3J0YWxpdMOpIGNvbW1lbmNlIMOgIHVuIG5pdmVhdSDDqWxldsOpIHB1aXMgZGltaW51ZSBqdXNxdSfDoCBsJ8OiZ2UgZGUgbCdhZG9sZXNjZW5jZSBhdmFudCBkJ2VudHJlcHJlbmRyZSB1bmUgY3JvaXNzYW5jZSBtb25vdG9uZS4gTGUgZ3JhcGhlIHN1aXQgbGEgbcOqbWUgdGVuZGFuY2UgcXVlbCBxdWUgc29pdCBsZSBwYXlzLiBDZXBlbmRhbnQsIGlsIGRpZmbDqHJlIHNlbG9uIGxlIHNleGUuIE9uIHBldXQgb2JzZXJ2ZXIgdW4gcXVvdGllbnQgZGUgbW9ydGFsaXTDqSBsw6lnw6hyZW1lbnQgcGx1cyDDqWxldsOpIGNoZXogbGVzIGhvbW1lcy4NCg0KLSBbIF0gIFRyYWNlciBsZXMgcmFwcG9ydHMgZW50cmUgbGVzIF9xdW90aWVudHMgZGUgbW9ydGFsaXTDqV8gZGVzIHBheXMgZXVyb3DDqWVucyBldCBsZXMgX3F1b3RpZW50cyBkZSBtb3J0YWxpdMOpXyBkZSB0b3VzIGxlcyBwYXlzIMOgIHRvdXMgbGVzIMOiZ2VzIHBvdXIgbCdhbm7DqWUgMTk0OC4NCmxlcyBfcXVvdGllbnRzIGRlIG1vcnRhbGl0w6lfIGRlcyBVU0EgZW4gMTk0OC4NCg0KYGBge3IgZmlnLmFzcCA9IDAuOCwgZmlnLndpZHRoID0gMTB9DQpsaWZlX3RhYmxlXzE5NDhfdXNhPC0gbGlmZV90YWJsZV8xOTQ4W2xpZmVfdGFibGVfMTk0OCRDb3VudHJ5PT0nVVNBJyxdDQojbGlmZV90YWJsZV8xOTQ4X3VzYQ0KDQpsaWZlX3RhYmxlXzE5NDhfcmF0aW88LSBsaWZlX3RhYmxlXzE5NDggJT4lDQogIG11dGF0ZSAoSW5fRXVyb3BlPSBpZl9lbHNlKENvdW50cnkgJWluJSBjKCdGcmFuY2UnLCdJdGFseScsJ1NwYWluJywnRW5nbGFuZCAmIFdhbGVzJywnTmV0aGVybGFuZHMnLCdTd2VkZW4nKSxULEYpICU+JSBhcy5mYWN0b3IoKSxxeF9yYXRpbz0gaWZfZWxzZShJbl9FdXJvcGU9PVQscXgvbGlmZV90YWJsZV8xOTQ4X3VzYSRxeCxxeCkpDQpsaWZlX3RhYmxlXzE5NDhfcmF0aW8gPC0gbGlmZV90YWJsZV8xOTQ4X3JhdGlvW2xpZmVfdGFibGVfMTk0OF9yYXRpbyRJbl9FdXJvcGU9PVQsXQ0KI+KAvGxpZmVfdGFibGVfMTk0OF9yYXRpbw0KDQooZ2dwbG90KGxpZmVfdGFibGVfMTk0OF9yYXRpbykrIGFlcyh4PUFnZSwgeT1xeF9yYXRpbywgZ3JvdXA9R2VuZGVyKQ0KICArZ2VvbV9saW5lKGFlcyhjb2xvcj1Db3VudHJ5KSkNCiAgK2dlb21fcG9pbnQoYWVzKGNvbG9yPUNvdW50cnkpLHNpemU9MC41LHNoYXBlPTE5KQ0KICArIHNjYWxlX2ZpbGxfYnJld2VyKCkNCiAgK2xhYnModGl0bGU9J1JhcHBvcnQgZW50cmUgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGRhbnMgbGVzIHBheXMgZXVyb3DDqWVucyBldCBhdXggRXRhdHMtVW5pcyDDoCBcbnRvdXMgbGVzIMOiZ2VzIGVuIDE5NDggJywgeT0nUmF0aW8gZW50cmUgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikpDQogICsgZmFjZXRfZ3JpZChHZW5kZXJ+LikNCiAgK3RoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID00NTAsIHdpZHRoPTgwMCkNCmBgYA0KDQotIFsgXSBDb21tZW50YWlyZQ0KDQpTdXIgY2UgcGxvdGx5IG9uIHBldXQgY29uc3RhdGVyIHF1ZSBkdXJhbnQgbCdhbm7DqWUgMTk0OCwgbCdFc3BhZ25lIGV0IGwnSXRhbGllIHBvc3PDqWRhaWVudCB1biB0YXV4IGRlIG1vcnRhbGl0w6kgYmllbiBzdXDDqXJpZXVyIMOgIGNlbHVpIGRlcyDDiXRhdHMtVW5pcyBldCBkdSByZXN0ZSBkZSBsJ0V1cm9wZS4gQ2UgcmFwcG9ydCBzJ8OpcXVpbGlicmUgw6AgbCfDomdlIGRlIDQwLiBPbiB2b2l0IMOpZ2FsZW1lbnQgcXVlIGxhIGNvdXJiZSBkZXMgZmVtbWVzIGVzdCBzdXDDqXJpZXVyZSDDoCBjZWxsZSBkZXMgaG9tbWVzLg0KTGVzIGF1dHJlcyBwYXlzIHF1YW50IMOgIGV1eCBzb250IGNvbXBhcmFibGVzIGF1IHRhdXggZGVzIFVTQS4NCg0KIyBFdm9sdXRpb24gZGVzIHRhdXggZGUgbW9ydGFsaXTDqSBkZXB1aXMgbGEgc2Vjb25kZSBndWVycmUgbW9uZGlhbGUNCg0KLSBbIF0gVHJhY2VyIGxlcyBfcXVvdGllbnRzIGRlIG1vcnRhbGl0w6lfIChjb2xvbm5lIGBxeGApIHBvdXIgbGVzDQpsZXMgZGV1eCBzZXhlcyBlbiBmb25jdGlvbiBkZSBsJ8OiZ2UgcG91ciBsZXMgYW5uw6llcyBgMTk0NiwgMTk1NiwgLi4uYCBqdXNxdSfDoCBgMjAxNmAgLg0KVXRpbGlzZXogbCdlc3Row6l0aXF1ZSBwb3VyIGRpc3Rpbmd1ZXIgbGVzIGFubsOpZXMuDQoNCi0gWyBdIEZhY2V0dGUgcGFyIGBHZW5kZXJgIGV0IGBDb3VudHJ5YC4NCg0KYGBge3IgZmlnLmFzcCA9IDEsIGZpZy53aWR0aCA9IDh9DQpsaWZlX3RhYmxlXzE5NDZfMjAxNiA8LSBsaWZlX3RhYmxlWyhsaWZlX3RhYmxlJFllYXIgJWluJSBzZXEoMTk0NiwyMDE2LDEwKSksXQ0KDQooZ2dwbG90KGxpZmVfdGFibGVfMTk0Nl8yMDE2KSthZXMoeD1BZ2UsIHk9cXgsZnJhbWU9WWVhciwgR3JvdXA9Q291bnRyeSkNCiAgK2dlb21fbGluZShhZXMoY29sb3I9R2VuZGVyKSkNCiAgK3NjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQWNjZW50IikNCiAgK2xhYnModGl0bGU9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6kgcGFyIGFnZSBlbiAxOTQ2LCAxOTU2LCAxOTY2LCAxOTc2LCAxOTg2LCAxOTk2LCAyMDA2LDIwMTYnLCB5PSdRdW90aWVudCBkZSBtb3J0YWxpdMOpJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikgKQ0KICArc2NhbGVfeV9sb2cxMChsYWJlbHM9c2NpZW50aWZpYykNCiAgK2ZhY2V0X2dyaWQoLn5Db3VudHJ5KQ0KICArIHRoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID0zNTAsIHdpZHRoPTgwMCkNCmBgYA0KDQotIFsgXSDDiWNyaXZleiB1bmUgZm9uY3Rpb24gYHJhdGlvX21vcnRhbGl0eV9yYXRlc2AgZG9udCBsYSBzaWduYXR1cmUgZXN0DQpgZnVuY3Rpb24oZGYsIHJlZmVyZW5jZV95ZWFyPTE5NDYsIHRhcmdldF95ZWFycz1zZXEoMTk0NiwgMjAxNiwgMTApKWANCnF1aSBwcmVuZCBjb21tZSBlbnRyw6llDQoNCiAgLSB1biB0YWJsZWF1IGRlIGRvbm7DqWVzIGF2ZWMgbGUgbcOqbWUgc2Now6ltYSBxdWUgYGxpZmVfdGFibGVgLA0KICAtIHVuZSBhbm7DqWUgZGUgcsOpZsOpcmVuY2UgYHJlZl95ZWFyYCBldA0KICAtIHVuZSBzw6lxdWVuY2UgZCdhbm7DqWVzIGB0YXJnZXRfeWVhcnNgLg0KDQpldCBxdWkgcmVudm9pZSB1biB0YWJsZWF1IGRlIGRvbm7DqWVzIGF2ZWMgbGUgc2Now6ltYSA6DQoNCg0KfCBOb20gZGUgbGEgY29sb25uZSB8IFR5cGUgZGUgY29sb25uZSB8DQp8Oi0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tfA0KfCBBbm7DqWUgfCBlbnRpZXIgfA0KfCBBZ2UgfCBlbnRpZXIgfA0KfCBxeCB8IGRvdWJsZSB8DQp8IHF4LnJlZl95ZWFyfCBkb3VibGUgfA0KfCBQYXlzIHwgZmFjdGV1cg0KfCBTZXhlIHwgRmFjdGV1cg0KDQpvw7kgYChQYXlzLCBBbm7DqWUsIEFnZSwgU2V4ZSlgIHNlcnQgZGUgX2Nsw6kgcHJpbWFpcmVfLA0KYHF4YCBkw6lzaWduZSBsZSBxdW90aWVudCBkZSBtb3J0YWxpdMOpIMOgIGBBZ2VgIHBvdXIgYEFubsOpZWAgZXQgYEdlbnJlYCBkYW5zIGBQYXlzYA0KdGFuZGlzIHF1ZSBgcXhfcmVmX3llYXJgIGluZGlxdWUgbGUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSDDoCBgQWdlYCBwb3VyIGwnYXJndW1lbnQgYHJlZmVyZW5jZV95ZWFyYC4NCmRhbnMgbGUgYHBheXNgIHBvdXIgbGUgYHNleGVgLg0KDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQpyYXRpb19tb3J0YWxpdHlfcmF0ZXMgPC0gZnVuY3Rpb24oZGYscmVmZXJlbmNlX3llYXIsIHRhcmdldF95ZWFyKXsNCiAgbGlmZV90YWJsZV90YXJnZXRfeSA8LSBkZltkZiRZZWFyICVpbiUgdGFyZ2V0X3llYXIsXQ0KICBsaWZlX3RhYmxlXzEgPC0gc2VsZWN0KGxpZmVfdGFibGVfdGFyZ2V0X3ksWWVhcixBZ2UscXgsZXgsQ291bnRyeSxHZW5kZXIpDQogIG5hbWVzKGxpZmVfdGFibGVfMSkgPC0gYygnWWVhcicsJ0FnZScsJ3F4JywncXgucmVmX3llYXInLCdDb3VudHJ5JywnR2VuZGVyJykNCiAgbGlmZV90YWJsZV9yZWZfeWVhciA8LWRmWyhkZiRZZWFyPT1yZWZlcmVuY2VfeWVhciksXQ0KICBsaWZlX3RhYmxlX3JlZl95ZWFyIDwtIHNlbGVjdChsaWZlX3RhYmxlX3JlZl95ZWFyLFllYXIsQWdlLHF4LENvdW50cnksR2VuZGVyKQ0KICBmb3IoaSBpbiAxOiBucm93KGxpZmVfdGFibGVfMSkpew0KICAgIGlmKGxpZmVfdGFibGVfMVtpLDFdPT1yZWZlcmVuY2VfeWVhcil7DQogICAgICBsaWZlX3RhYmxlXzFbaSw0XSA8LSBsaWZlX3RhYmxlXzFbaSwzXQ0KICAgIH0NCiAgICBlbHNlIHsNCiAgICAgICAgbGlmZV90YWJsZV8yIDwtIGxpZmVfdGFibGVfcmVmX3llYXJbKGxpZmVfdGFibGVfcmVmX3llYXIkQWdlPT1hcy5udW1lcmljKGxpZmVfdGFibGVfMVtpLDJdKSkgJiAobGlmZV90YWJsZV9yZWZfeWVhciRDb3VudHJ5PT1hcy5jaGFyYWN0ZXIobGlmZV90YWJsZV8xW2ksNV0pKSAmIGxpZmVfdGFibGVfcmVmX3llYXIkR2VuZGVyPT1hcy5jaGFyYWN0ZXIobGlmZV90YWJsZV8xW2ksNl0pLF0NCiAgICAgIGxpZmVfdGFibGVfMVtpLDRdIDwtIGxpZmVfdGFibGVfMlsxLDNdDQogICAgfQ0KICB9DQogIHJldHVybiAobGlmZV90YWJsZV8xKQ0KfQ0KDQpsaWZlX3RhYmxlXzE8LSByYXRpb19tb3J0YWxpdHlfcmF0ZXMobGlmZV90YWJsZSwxOTQ2LHNlcSgxOTQ2LDIwMTYsMTApKQ0KaGVhZChsaWZlX3RhYmxlXzEpDQpgYGAgIA0KDQotIFsgXSBEZXNzaW5leiBkZXMgZ3JhcGhpcXVlcyBhZmZpY2hhbnQgbGUgcmFwcG9ydCAkcV97eCx0fS9xX3t4LCAxOTQ2fSQgcG91ciBsZXMgw6JnZXMgJHggXGluIDEsIFxsZG90cywgOTAkIGV0IGwnYW5uw6llICR0JCBwb3VyICR0IFxpbiAxOTQ2LCBcbGRvdHMsIDIwMTYkLg0KZXQgbCdhbm7DqWUgJHQkIHBvdXIgJHQgXGluIDE5NDYsIFxsZG90cywgMjAxNiQgb8O5ICRxX3t4LHR9JCBlc3QgbGUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSDDoCBsJ8OiZ2UgJHgkIHBlbmRhbnQgbCdhbm7DqWUgJHQkLg0KDQogIDEuIFsgXSBUcmFpdGVyIGxlcyBkZXV4IHNleGVzIGV0IGxlcyBkZXV4IHBheXMgYEVzcGFnbmVgLCBgSXRhbGllYCwgYEZyYW5jZWAsIGBBbmdsZXRlcnJlIGV0IFBheXMgZGUgR2FsbGVzYCwgYFVTQWAsIGBTdcOoZGVgLCBgUGF5cy1CYXNgLg0KICAxLiBbIF0gVW5lIGdyYXBoaXF1ZSBjb3JyZWN0ZW1lbnQgZmFjZXR0w6kgZXN0IHN1ZmZpc2FudCAgKGBmYWNldF9ncmlkKClgLCBgZmFjZXRfd3JhcCgpYCkuDQoNCg0KYGBge3IgIGZpZy5hc3AgPSAxLCBmaWcud2lkdGggPSA4fQ0KbGlmZV90YWJsZV8xPC0gcmF0aW9fbW9ydGFsaXR5X3JhdGVzKGxpZmVfdGFibGUsMTk0NixzZXEoMTk0NiwyMDE2LDEwKSkNCg0KbGlmZV90YWJsZV8xIDwtIGxpZmVfdGFibGVfMVsobGlmZV90YWJsZV8xJEFnZSAlaW4lIHNlcSgxLDkwLDEpKSxdDQoNCmxpZmVfdGFibGVfMTwtIGxpZmVfdGFibGVfMSAlPiUNCiAgbXV0YXRlIChSYXRpbz1xeC9xeC5yZWZfeWVhcikNCg0KKGdncGxvdChsaWZlX3RhYmxlXzEpK2Flcyh4PUFnZSwgeT1SYXRpbyxmcmFtZT1ZZWFyLGdyb3VwPUNvdW50cnkpDQogICtnZW9tX2xpbmUoYWVzKGNvbG9yPUdlbmRlcixsaW5ldHlwZT1HZW5kZXIpKQ0KDQogICtzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkFjY2VudCIpDQogICtsYWJzKHRpdGxlPSdSYXRpbyBkZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgcGFyIGFnZScsIHk9J1JhdGlvIGRlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqScpDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpICkNCiAgK3NjYWxlX3lfbG9nMTAobGFiZWxzPXNjaWVudGlmaWMpDQogICtmYWNldF9ncmlkKENvdW50cnl+LikNCiAgK3RoZW1lX2J3KCkpICU+JQ0KICBwbG90bHk6OmdncGxvdGx5KGhlaWdodCA9IDY1MCwgd2lkdGg9NzUwKQ0KYGBgDQoNCi0gQ29tbWVudGFpcmUNCg0KQXUgZmlsIGR1IHRlbXBzLCBvbiBwZXV0IHZvaXIgcXVlIGxhIGNvdXJiZSBkdSByYXRpbyBkZXMgcXVvdGllbnRzIGVzdCBkZSBwbHVzIGVuIHBsdXMgYmFzc2UgcGFyIHJhcHBvcnQgYXV4IGFubsOpZXMgcHLDqWPDqWRlbnRlcy4gT24gcGV1dCBjb25jbHVyZSBxdWUgbGUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSBkaW1pbnVlIGF2ZWMgbGVzIGFubsOpZXMsIGNlIHF1aSBwb3VycmFpdCBzJ2V4cGxpcXVlciBwYXIgbCdhbcOpbGlvcmF0aW9uIGRlcyBjb25kaXRpb25zIGRlIHZpZS4gRGUgcGx1cywgb24gcGV1dCByZW1hcnF1ZXIgcXVlIGxlcyByYXRpb3MgZGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGRlcyBob21tZXMgc29udCBsw6lnw6hyZW1lbnQgYXUtZGVzc3VzIGRlcyBmZW1tZXMuDQoNCg0KIyBUZW5kYW5jZXMNCg0KDQotIFsgXSBUcmFjZXIgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGF1eCDDomdlcyAwLCAxLCA1JCBlbiBmb25jdGlvbiBkdSB0ZW1wcy4gRmFjZXR0ZSBwYXIgc2V4ZSBldCBwYXIgcGF5cw0KDQpgYGB7ciBmaWcuYXNwID0gMSwgZmlnLndpZHRoID0gOH0NCmxpZmVfdGFibGVfMF8xXzUgPC0gbGlmZV90YWJsZSAlPiUNCiAgZmlsdGVyKGxpZmVfdGFibGUkQWdlICVpbiUgYygwLDEsNSkgKQ0KDQpwMzwtIChnZ3Bsb3QobGlmZV90YWJsZV8wXzFfNSwgYWVzKHg9WWVhciwgeT1xeCwgZnJhbWU9QWdlLGdyb3VwPUdlbmRlcikpDQorZ2VvbV9saW5lKGFlcyhjb2xvcj1Db3VudHJ5KSkNCiAgK2xhYnModGl0bGU9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6kgcGFyIGFnZScsIHk9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6knKQ0KICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZC5pdGFsaWMiKSkNCiAgKyBmYWNldF9ncmlkKENvdW50cnl+R2VuZGVyKStzY2FsZV95X2xvZzEwKGxhYmVscz1zY2llbnRpZmljKQ0KICArIHRoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID0gNjAwLCB3aWR0aD03NTApDQoNCnAzDQpgYGANCg0KLSBbIF0gQ29tbWVudGFpcmUNCg0KQ2UgZmFjZXR0ZSB0w6ltb2lnbmUgZGUgbCfDqXZvbHV0aW9uIGRlIGxhIG1vcnRhbGl0w6kgaW5mYW50aWxlIGF1IGNvdXJzIGR1IHRlbXBzIHBvdXIgbGVzIMOiZ2VzIDAsMSBldCA1LiBDb21tZSB2dSBwcsOpY8OpZGVtbWVudCwgb24gcmVtYXJxdWUgdW5lIGRpbWludXRpb24gZHUgdGF1eCBkZSBtb3J0YWxpdMOpIGF1IGZpbCBkZXMgYW5uw6llcy5EZSBwbHVzLCBsYSBjb3VyYmUgZGVzIGhvbW1lcyBlc3QgcHJlc3F1ZSBpZGVudGlxdWUgw6AgY2VsbGUgZGVzIGZlbW1lcy4NCg0KDQoNCi0gWyBdIFRyYWNleiBsZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgYXV4IMOiZ2VzIGRlICQxNSwgMjAsIDQwLCA2MCQgZW4gZm9uY3Rpb24gZHUgdGVtcHMuIEZhY2V0dGUgcGFyIGBHZW5kZXJgIGV0IGBDb3VudHJ5YC4NCmBgYHtyIGZpZy5hc3AgPSAxLCBmaWcud2lkdGggPSA4fQ0KbGlmZV90YWJsZV8xNV82MCA8LSBsaWZlX3RhYmxlICU+JQ0KICBmaWx0ZXIobGlmZV90YWJsZSRBZ2UlaW4lIGMoMTUsMjAsNDAsNjApKQ0KIA0KcDQ8LSAoZ2dwbG90KGxpZmVfdGFibGVfMTVfNjAsIGFlcyh4PVllYXIsIHk9cXgsIGZyYW1lPUFnZSwgZ3JvdXA9R2VuZGVyKSkNCitnZW9tX2xpbmUoYWVzKGNvbG9yPUNvdW50cnkpKQ0KICArbGFicyh0aXRsZT0nUXVvdGllbnQgZGUgbW9ydGFsaXTDqSBwYXIgYW5uw6llJywgeT0nUXVvdGllbnQgZGUgbW9ydGFsaXTDqScsIHg9J0FubsOpZScpDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpKQ0KICArIGZhY2V0X2dyaWQoQ291bnRyeX5HZW5kZXIpK3NjYWxlX3lfbG9nMTAobGFiZWxzPXNjaWVudGlmaWMpDQogICsgdGhlbWVfYncoKSklPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPSA2MDAsIHdpZHRoPTc1MCkNCg0KcDQNCmBgYA0KDQotIFsgXSBDb21tZW50YWlyZQ0KDQpJbnTDqXJlc3NvbnMtbm91cyDDoCBwcsOpc2VudCBhdXggw6JnZXMgMTUtMjAtNDAtNjAuIE9uIHBldXQgb2JzZXJ2ZXIsIHVuZSBmb2lzIGRlIHBsdXMsIGxhIGRpbWludXRpb24gZHUgdGF1eCBkZSBtb3J0YWxpdMOpIGF1IHRyYXZlcnMgZGVzIGFubsOpZXMuIENlcGVuZGFudCwgbGVzIDIgZ3VlcnJlcyBtb25kaWFsZXMgZW50cmHDrm5lbnQgZGVzIHBpY3Mgc3VyIGxlcyBjb3VyYmVzICgxOTE0LTE5MTgsIDE5MzktMTk0NSksIGVuIHBhcnRpY3VsaWVyIGNoZXogbGVzIGhvbW1lcyBkZSAxNS0yMCBhbnMuDQoNCiMgUsOpYXJyYW5nZW1lbnQNCg0KLSBbIF0gQSBwYXJ0aXIgZHUgdGFibGVhdSBkZSBkb25uw6llcyBgbGlmZV90YWJsZWAsIGNhbGN1bGV6IHVuIGF1dHJlIHRhYmxlYXUgZGUgZG9ubsOpZXMgYXBwZWzDqSBgbGlmZV90YWJsZV9waXZvdGAsICBhdmVjIGxlcyBjbMOpcyBwcmltYWlyZXMgYENvdW50cnlgLCBgR2VuZGVyYCBldCBgWWVhcmAsIGF2ZWMgdW5lIGNvbG9ubmUgcG91ciBjaGFxdWUgYEFnZWAgZGUgYDBgIMOgIGAxMTBgLg0KDQpWb3VzIHBvdXZleiB1dGlsaXNlciBsZXMgZm9uY3Rpb25zICBgcGl2b3Rfd2lkZXJgLCBgcGl2b3RfbG9uZ2VyYCBkdSBwYWNrYWdlICBgdGlkeXI6OmAuDQoNCkxlIHNjaMOpbWEgZHUgcsOpc3VsdGF0IGRldnJhaXQgYXZvaXIgbCdhc3BlY3Qgc3VpdmFudDoNCg0KfCBOb20gZGUgY29sb25uZSB8IFR5cGUgICAgfA0KfDotLS0tLS0tLS0tLS18Oi0tLS0tLS0tfA0KfCBDb3VudHJ5ICAgICB8IGZhY3RvciAgfA0KfCBHZW5kZXIgICAgICB8IGZhY3RvciAgfA0KfCBZZWFyICAgICAgICB8IGludGVnZXIgfA0KfCBgMGAgICAgICAgICB8IGRvdWJsZSAgfA0KfCBgMWAgICAgICAgICB8IGRvdWJsZSAgfA0KfCBgMmAgICAgICAgICB8IGRvdWJsZSAgfA0KfCBgM2AgICAgICAgICB8IGRvdWJsZSAgfA0KfCAkXHZkb3RzJCAgICB8ICRcdmRvdHMkfA0KDQpgYGB7cn0NCmxpZmVfdGFibGVfcGl2b3QgPC0gc2VsZWN0KGxpZmVfdGFibGUsQ291bnRyeSxHZW5kZXIsWWVhcixBZ2UscXgpDQpsaWZlX3RhYmxlX3Bpdm90IDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tPUFnZSwgdmFsdWVzX2Zyb209cXgpDQpoZWFkKGxpZmVfdGFibGVfcGl2b3QpDQpgYGANCg0KLSBbIF0gw4AgcGFydGlyIGRlICBgbGlmZV90YWJsZV9waXZvdGAgY2FsY3VsZXIgbCdlc3DDqXJhbmNlIGRlIHZpZSDDoCBsYSBuYWlzc2FuY2UgIHBvdXIgY2hhcXVlIGNsw6kgYENvdW50cnksIEdlbmRlcmAgYW5kIGBZZWFyYC4NCg0KYGBge3J9DQpuZXdfdGFiIDwtIGxpZmVfdGFibGUgJT4lDQogIHNlbGVjdChHZW5kZXIsWWVhcixBZ2UsQ291bnRyeSxseCklPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9QWdlLCB2YWx1ZXNfZnJvbSA9IGx4KS0+bGlmZV90YWJsZV9waXZvdDINCg0KbGYxIDwtIHNlbGVjdChsaWZlX3RhYmxlX3Bpdm90MixHZW5kZXIsWWVhcixDb3VudHJ5KQ0KbGYyIDwtIHN1YnNldChsaWZlX3RhYmxlX3Bpdm90Miwgc2VsZWN0ID0gLWMoR2VuZGVyLFllYXIsQ291bnRyeSkpDQplc3BlIDwtIHZlY3RvcigibnVtZXJpYyIsbnJvdyhsZjIpKQ0KZm9yIChsIGluIDE6bnJvdyhsZjIpKQ0Kew0KICBlc3BlW2xdID0gc3VtKGxmMltsLF0pLzEwMDAwMA0KfQ0KDQpuZXdfdGFiMiA8LSBjYmluZChsZjEsZXNwZSkNCmhlYWQobmV3X3RhYjIpDQpgYGANCg0KIyBFc3DDqXJhbmNlIGRlIHZpZQ0KDQotIFsgXSDDiWNyaXJlIHVuZSBmb25jdGlvbiBxdWkgcHJlbmQgZW4gZW50csOpZSB1biB2ZWN0ZXVyIGRlIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpLCBhaW5zaSBxdSd1biDDomdlLCBldCByZW52b2llIGwnZXNww6lyYW5jZSBkZSB2aWUgcsOpc2lkdWVsbGUgY29ycmVzcG9uZGFudCBhdSB2ZWN0ZXVyIGV0IMOgIGwnw6JnZSBkb25uw6kuDQoNCmBgYHtyLGVjaG89VFJVRX0NCmVzcF9yZXMgPC0gZnVuY3Rpb24odl9xeCxhZ2Upew0KICANCiAgc3VtID0gMA0KICBmb3IgKCBpIGluIGFnZSA6IDEwOSl7DQogICAgcHJvID0gMQ0KICAgIGZvciAoaiBpbiBhZ2UgOiBpKXsNCiAgICAgIG0gPSB2X3F4W2pdLygxLSh2X3F4W2pdLzIpKQ0KICAgICAgcHJvID0gcHJvICogKDEtbSkNCiAgICB9DQogICAgc3VtID0gc3VtICsgcHJvDQogIH0NCiAgcmV0dXJuKGFzLm51bWVyaWMoc3VtKSkNCn0NCmBgYA0KDQoNCi0gWyBdIMOJY3JpdmV6IHVuZSBmb25jdGlvbiBxdWkgcHJlbmQgY29tbWUgZW50csOpZSB1biB0YWJsZWF1IGRlIGRvbm7DqWVzIGF2ZWMgbGUgbcOqbWUgc2Now6ltYSBxdWUgYGxpZmVfdGFibGVgIGV0IHJldG91cm5lIHVuIHRhYmxlYXUgZGUgZG9ubsOpZXMgYXZlYyBsZXMgY29sb25uZXMgYENvdW50cnlgLCBgR2VuZGVyYCwgYFllYXJgLCBgQWdlYCBkw6lmaW5pc3NhbnQgdW5lIGNsw6kgcHJpbWFpcmUgZXQgdW5lIGNvbG9ubmUgYHJlc19sZXhgIGNvbnRlbmFudCBsJ2VzcMOpcmFuY2UgZGUgdmllIHLDqXNpZHVlbGxlIGNvcnJlc3BvbmRhbnQgw6AgbGEgY2zDqSBwcmltYWlyZS4NCg0KYGBge3IsIGVjaG89VFJVRX0NCnRhYl9lc3BfcmVzIDwtIGZ1bmN0aW9uKGRmKXsNCiAgZGYgJT4lDQogICAgc2VsZWN0KENvdW50cnksR2VuZGVyLFllYXIsQWdlLHF4KSAlPiUNCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gQWdlLCB2YWx1ZXNfZnJvbSA9IHF4KSAtPiBkZg0KICBmb3IoaSBpbiAxOm5yb3coZGYpKXsNCiAgICB2X3F4IDwtIGRmW2ksNDoxMTNdDQogICAgdl9xeCA8LSBhcy5udW1lcmljKHZfcXgpDQogICAgDQogICAgZm9yKGogaW4gNDoxMTMpew0KICAgICAgZGZbaSxqXSA9IGVzcF9yZXModl9xeCxqLTMpDQogICAgfQ0KICB9DQogIGRmID0gcGl2b3RfbG9uZ2VyKGRmLGNvbHMgPSAtYyhDb3VudHJ5LEdlbmRlcixZZWFyKSwgbmFtZXNfdG8gPSAiQWdlIiwgdmFsdWVzX3RvID0iUmVzX2xleCIpDQogIHJldHVybihkZikNCn0NCg0KbGlmZV90YWJsZV9yZXNfbGV4IDwtIHRhYl9lc3BfcmVzKGxpZmVfdGFibGUpDQpoZWFkKGxpZmVfdGFibGVfcmVzX2xleCkNCmBgYA0KDQoNCi0gWyBdIEFmaW4gZGUgY2FsY3VsZXIgbGVzIGVzcMOpcmFuY2VzIGRlIHZpZSByw6lzaWR1ZWxsZXMsIHZvdXMgcG91dmV6IGVudmlzYWdlciBkJ3V0aWxpc2VyIGxlcyBmb25jdGlvbnMgImZlbsOqdHJlIiBgd2luZG93YCBxdWkgcGVybWV0dGVudCBkZSBkw6lmaW5pciBkZXMgZmVuw6p0cmVzIGFwcHJvcHJpw6llcy4gTGUgcGFxdWV0IGBkcGx5cmAgbidvZmZyZSBwYXMgdW5lIHRyw6hzIHJpY2hlIGludGVyZmFjZSAoQVBJKSBwb3VyIGxlcyBmb25jdGlvbnMgImZlbsOqdHJlIiAod2luZG93IGZ1bmN0aW9ucykuIExlIHBhcXVldCBgZGJwbHlyYCBsZSBmYWl0Lg0KDQoNCi0gWyBdIFRyYWNleiBsJ2VzcMOpcmFuY2UgZGUgdmllIHLDqXNpZHVlbGxlIGVuIGZvbmN0aW9uIGRlIGBZZWFyYCBhdXggw6JnZXMgZGUgJDYwJCBldCAkNjUkLiBDcsOpZXIgdW5lDQoNCg0KYGBge3J9DQpsaWZlX3RhYmxlXzYwXzY1IDwtIHNlbGVjdChsaWZlX3RhYmxlX3Jlc19sZXgsWWVhcixBZ2UsR2VuZGVyLENvdW50cnksUmVzX2xleCkNCmxpZmVfdGFibGVfNjBfNjUgPC0gbGlmZV90YWJsZV82MF82NSAlPiUgZmlsdGVyKGxpZmVfdGFibGVfNjBfNjUkQWdlICVpbiUgYyg2MCw2NSkpDQoNCnA1PC0gKGdncGxvdChsaWZlX3RhYmxlXzYwXzY1LCBhZXMoeD1ZZWFyLCB5PVJlc19sZXgsIGZyYW1lPUFnZSkpDQorZ2VvbV9saW5lKCBhZXMoY29sb3I9Q291bnRyeSAsR3JvdXA9R2VuZGVyKSkNCiAgK2xhYnModGl0bGU9IkwnZXNww6lyYW5jZSBkZSB2aWUgcsOpc2lkdWVsbGUgw6AgbCfDomdlIGRlIDYwIGV0IDY1IGFucyIsIHk9ImwnZXNwZXJhbmNlIGRlIHZpZSByw6lzaWR1ZWxsZSIsIHg9J2FubsOpZScpDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpKQ0KICArIGZhY2V0X2dyaWQoQ291bnRyeX5HZW5kZXIpDQogICsgdGhlbWVfYncoKSklPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPSA2NTAsIHdpZHRoPTc1MCkNCnA1DQpgYGANCg0KIyBQQ0EgZXQgU1ZEIHN1ciBsZXMgdGFibGVzIGRlIGxvZy1tb3J0YWxpdMOpDQoNCi0gWyBdIENob2lzaXNzZXogdW4gcGF5cywgdW4gc2V4ZSwgdW5lIHBsYWdlIGQnYW5uw6llcyBgMTk0ODoyMDEwYC4NCkV4dHJheWV6IGxlcyBsaWduZXMgY29ycmVzcG9uZGFudGVzIGRlIGBsaWZlX3RhYmxlX3Bpdm90YC4gUHJlbmRyZSBsZXMgX2xvZ2FyaXRobWVzXyBkZXMNCnF1YW90aWVudHMgZGUgbW9ydGFsaXTDqSBldCBlZmZlY3R1ZXogdW5lIGFuYWx5c2UgZW4gY29tcG9zYW50ZXMgcHJpbmNpcGFsZXMuDQrDiXZhbHVleiBsZXMgcsOpc3VsdGF0cyBkZSBsJ0FDUCBhdmVjIGV0IHNhbnMgY2VudHJhZ2UgZXQgbm9ybWFsaXNhdGlvbiBkZXMgY29sb25uZXMuDQoNCg0KDQpgYGB7cn0NCmNvdW50cnkgPC0gIkZyYW5jZSINCmdlbmRlciA8LSAiRmVtYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYSAlPiUgIHNlbGVjdChZZWFyKQ0KbGlmZV9iaXMgPSBjYmluZChsaWZlX3llYXIsIGxpZmVfdGFibGVfcGNhKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2EgPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCiNsaWZlX3RhYmxlX3BjYQ0KDQojQUNQIHLDqWR1aXRlIGV0IGNlbnRyw6llIA0KcmVzLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhLHNjYWxlPVQsY2VudGVyID1UKQ0KDQojQUNQIG5vbiByw6lkdWl0ZSBldCBjZW50csOpZQ0KcmVzMi5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYSxzY2FsZT1GLGNlbnRlciA9VCkNCg0KI0FDUCByZWR1aXRlIGV0IG5vbiBjZW50csOpZQ0KcmVzMy5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYSxzY2FsZT1ULGNlbnRlciA9RikNCg0KI0FDUCBub24gcmVkdWl0ZSBldCBub24gY2VudHLDqWUNCnJlczQuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2Esc2NhbGU9RixjZW50ZXI9RikNCg0KI0NlcmNsZSBkZSBjb3Jyw6lsYXRpb24gcsOpZHVpdGUgZXQgY2VudHLDqWUgDQpmdml6X3BjYV92YXIocmVzLmFjcCwgY29sLnZhciA9ICJibGFjayIsdGl0bGU9IkNlcmNsZSBkZSBjb3Jyw6lsYXRpb24gZCd1bmUgQUNQIGNlbnRyw6llIGV0IHLDqWR1aXRlIixyZXBlbCA9IFRSVUUpDQoNCiNDZXJjbGUgZGUgY29ycsOpbGF0aW9uIG5vbiByw6lkdWl0ZSBldCBjZW50csOpZQ0KejIgPC0gcmVzMi5hY3AkeA0KY2MyIDwtIGNvcihsaWZlX3RhYmxlX3BjYSx6MlssMTpucm93KGxpZmVfdGFibGVfcGNhKV0pDQpzLmNvcmNpcmNsZShjYzIpDQoNCiNDZXJjbGUgZGUgY29ycsOpbGF0aW9uIHJlZHVpdGUgZXQgbm9uIGNlbnRyw6llDQp6MyA8LSByZXMzLmFjcCR4DQpjYzMgPC0gY29yKGxpZmVfdGFibGVfcGNhLHozWywxOm5yb3cobGlmZV90YWJsZV9wY2EpXSkNCnMuY29yY2lyY2xlKGNjMykNCg0KI0NlcmNsZSBkZSBjb3Jyw6lsYXRpb24gbm9uIHJlZHVpdGUgZXQgbm9uIGNlbnRyw6llDQp6NCA8LSByZXM0LmFjcCR4DQpjYzQgPC0gY29yKGxpZmVfdGFibGVfcGNhLHo0WywxOm5yb3cobGlmZV90YWJsZV9wY2EpXSkNCnMuY29yY2lyY2xlKGNjNCkNCg0KI3NjcmVlcGxvdHMNCg0KZnZpel9laWcocmVzLmFjcCwgYWRkbGFiZWxzPVQsIGhqdXN0PS0wLjMsdGl0bGU9IlNjcmVlcGxvdCBkJ3VuZSBBQ1AgY2VudHLDqWUgZXQgcsOpZHVpdGUiKQ0KZnZpel9laWcocmVzMi5hY3AsIGFkZGxhYmVscz1ULCBoanVzdD0tMC4zLHRpdGxlPSJTY3JlZXBsb3QgZCd1bmUgQUNQIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSIpIA0KZnZpel9laWcocmVzMy5hY3AsIGFkZGxhYmVscz1ULCBoanVzdD0tMC4zLHRpdGxlPSJTY3JlZXBsb3QgZCd1bmUgQUNQIG5vbiBjZW50csOpZSBldCByw6lkdWl0ZSIpDQpmdml6X2VpZyhyZXM0LmFjcCwgYWRkbGFiZWxzPVQsIGhqdXN0PS0wLjMsdGl0bGU9IlNjcmVlcGxvdCBkJ3VuZSBBQ1Agbm9uIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSIpDQoNCiMgYmlwbG90cw0KZnZpel9wY2FfYmlwbG90KHJlcy5hY3AsIHJlcGVsID0gVFJVRSwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1AgY2VudHLDqWUgZXQgcsOpZHVpdGUiKSANCmZ2aXpfcGNhX2JpcGxvdChyZXMyLmFjcCwgcmVwZWwgPSBUUlVFICwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1AgY2VudHLDqWUgZXQgbm9uIHLDqWR1aXRlIikgDQpmdml6X3BjYV9iaXBsb3QocmVzMy5hY3AsIHJlcGVsID0gVFJVRSwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1Agbm9uIGNlbnRyw6llIGV0IHLDqWR1aXRlIikgDQpmdml6X3BjYV9iaXBsb3QocmVzNC5hY3AsIHJlcGVsID0gVFJVRSwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1Agbm9uIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSIpIA0KDQpgYGANCg0KLSBbIF0gQ29tbWVudGV6IGxlKHMpIGdyYXBoZShzKSBkJ2FmZmljaGFnZS4NCg0KT24gcGV1dCBjb25zdGF0ZXIgcXVlIGRhbnMgdG91cyBsZXMgc2NyZWVwbG90cywgbGEgcHJlbWnDqHJlIGNvbXBvc2FudGUgcHJpbmNpcGFsZSBleHBsaXF1ZSBwbHVzIGRlIDkzICUgZGUgbGEgdmFyaWFuY2UuDQpQb3VyIGwnQUNQIGNlbnRyw6llIGV0IHLDqWR1aXRlLCBpbCBmYXV0IGdhcmRlciBsZXMgMiBwcmVtacOocmVzIGNvbXBvc2FudGVzIHByaW5jaXBhbGVzLCBjYXIgZWxsZXMgcmVwcsOpc2VudGVudCA5Ni4yICUgZGUgbGEgdmFyaWFuY2UgZXhwbGlxdcOpZS4gRW5zdWl0ZSwgcG91ciBsZSBjYXMgZCd1bmUgQUNQIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSwgaWwgZmF1dCDDqWdhbGVtZW50IGdhcmRlciBsZXMgMiBwcmVtacOocmVzIGNvbXBvc2FudGVzIHByaW5jaXBhbGVzLCBjYXIgZWxsZXMgcmVwcsOpc2VudGVudCA5Ni41ICUgZGUgbGEgdmFyaWFuY2UgZXhwbGlxdcOpZS5FbmZpbiwgcG91ciBsZXMgQUNQIG5vbiBjZW50csOpZSBldCByw6lkdWl0ZSBldCBub24gY2VudHLDqWUgZXQgbm9uIHLDqWR1aXRlLCBvbiBuZSBnYXJkZSBxdWUgbGEgcHJlbWnDqHJlIGNvbXBvc2FudGUsIGNhciBlbGxlIHJlcHLDqXNlbnRlIGRhbnMgbGVzIGRldXggY2FzIDk5LjkgJSBkZSBsYSB2YXJpYW5jZSBleHBsaXF1w6llLiBBdXRyZW1lbnQgZGl0LCA5OS45ICUgZGUgbCdpbmZvcm1hdGlvbiAodmFyaWFuY2UpIGVzdCBjb250ZW51ZSBkYW5zIGxlcyBkb25uw6llcyBkZSBsYSBwcmVtacOocmUgY29tcG9zYW50ZSBwcmluY2lwYWxlLg0KDQoNCi0gWyBdIENvbW1lbnRlciBsZShzKSBjZXJjbGUocykgZGUgY29ycsOpbGF0aW9uDQoNClN1ciBsZXMgZGV1eCBwcmVtaWVycyBjZXJjbGVzIGRlIGNvcnLDqWxhdGlvbiAoY2VudHLDqSByw6lkdWl0LCBjZW50csOpIG5vbiByw6lkdWl0KSBvbiByZW1hcnF1ZSBxdWUgbGVzIHZhcmlhYmxlcyAwLDEsLi4uLDEwOSwgcXVpIGNvcnJlc3BvbmRlbnQgYXV4IMOiZ2VzIHNvbnQgY29ycsOpbMOpZXMgbsOpZ2F0aXZlbWVudCDDoCBsYSBwcmVtacOocmUgY29tcG9zYW50ZSBwcmluY2lwYWxlIGV0IHNvbnQgY29ycsOpbMOpZXMgZW50cmUgZWxsZXMuIERlIHBsdXMsIG9uIGNvbnN0YXRlIHF1J2VsbGVzIHNvbnQgdHLDqHMgcHJvY2hlcyBkdSBjZXJjbGUgZGUgY29ycsOpbGF0aW9ucyBkb25jIGVsbGVzIHNvbnQgYmllbiByZXByw6lzZW50w6llcy4NCkNvbmNlcm5hbnQgbGVzIDIgZGVybmllcnMgY2VyY2xlcyBkZSBjb3Jyw6lsYXRpb25zKG5vbiBjZW50csOpIGV0IHLDqWR1aXQsIG5vbiBjZW50csOpIGV0IG5vbiByw6lkdWl0KSwgbGVzIGZsw6hjaGVzIHNvbnQgZGUgbG9uZ3VldXIgc3Vww6lyaWV1cmUgw6AgMSwgY2UgcXVpIGVzdCBub3JtYWwsIGNhciBsZXMgZG9ubsOpZXMgbmUgc29udCBwYXMgY2VudHLDqWVzLiBEZSBwbHVzLCBvbiByZW1hcnF1ZSBzdXIgY2VzIGRldXggY2VyY2xlcyBxdWUgbGVzIMOiZ2VzIHNvbnQgY29ycsOpbMOpcyBzdXIgbGVzIGRldXggY29tcG9zYW50ZXMgcHJpbmNpcGFsZXMuDQoNCi0gWyBdIENvbW1lbnRleiBsZShzKSBgYmlwbG90KHMpYA0KDQpUb3V0IGQnYWJvcmQsIGxlcyBpbmRpdmlkdXMgY29ycmVzcG9uZGVudCBkYW5zIG5vdHJlIMOpdHVkZSBhdXggYW5uw6llcyBldCBsZXMgdmFyaWFibGVzIDAsMSwuLi4sMTA5IGNvcnJlc3BvbmRlbnQgYXV4IMOiZ2VzLiBVbiBpbmRpdmlkdSBxdWkgc2UgdHJvdXZlIGR1IG3Dqm1lIGPDtHTDqSBk4oCZdW5lIHZhcmlhYmxlIGRvbm7DqWUgYSB1bmUgdmFsZXVyIMOpbGV2w6llIHBvdXIgY2V0dGUgdmFyaWFibGUgZXQgdW4gaW5kaXZpZHUgcXVpIHNlIHRyb3V2ZSBkYW5zIGxlIGPDtHTDqSBvcHBvc8OpIGTigJl1bmUgdmFyaWFibGUgZG9ubsOpZSBhIHVuZSBmYWlibGUgdmFsZXVyIHBvdXIgY2V0dGUgdmFyaWFibGUuDQoNCkRhbnMgbGVzIDIgcHJlbWllcnMgYmlwbG90cywgb24gY29uc3RhdGUgcXVlIHByYXRpcXVlbWVudCBsYSBtb2l0acOpIGRlcyBpbmRpdmlkdXMgc2UgdHJvdXZlbnQgZHUgbcOqbWUgY8O0dMOpIHF1ZSBjZXV4IGRlcyB2YXJpYWJsZXMuIFRhbmRpcyBxdWUgZGFucyBsZSBkZXJuaWVyIGJpcGxvdCwgdG91cyBsZXMgaW5kaXZpZHVzIHNlIHRyb3V2ZW50IGR1IGNvdMOpIG9wcG9zw6kgw6AgY2V1eCBkZXMgdmFyaWFibGVzLiBQdWlzLCBzdXIgbGUgYmlwbG90IGRlIGwnQUNQIG5vbiBjZW50csOpZSBldCByw6lkdWl0ZSwgb24gbmUgdm9pdCBwbHVzIGxlcyBpbmRpdmlkdXMuDQoNCg0KLSBbIF0gQ2hvaXNpc3NleiBsYSBjb21iaW5haXNvbiBkZSBjZW50cmFnZSBldCBkZSBub3JtYWxpc2F0aW9uIHF1aSB2b3VzIHNlbWJsZSBsYSBwbHVzIHBlcnRpbmVudGUuIE1vdGl2ZXogdm90cmUgY2hvaXgNCg0KYGBge3J9DQpkZjwtIGxpZmVfdGFibGVfcGl2b3QgDQpkZl9udW08LSBkcGx5cjo6c2VsZWN0KGRmLC1jKFllYXIsQ291bnRyeSxHZW5kZXIpKQ0KDQpsaXN0X3BjYV9kZiA8LSBtYXAyKC54ID0gcmVwKGMoRkFMU0UsIFRSVUUpLCAyKSwNCiAgICAueSA9IHJlcChjKEZBTFNFLCBUUlVFKSwgYygyLDIpKSwNCiAgICB+IHByY29tcChkZl9udW0sIGNlbnRlcj0gLngsIHNjYWxlLj0ueSwgcmFuaz00KQ0KKQ0KbmFtZXMobGlzdF9wY2FfZGYpIDwtc3RyaW5ncjo6IHN0cl9jKCJwY2FfbGlmZSIsDQogICAgYygiIiwgImMiLCAicyIsICJjX3MiKSwNCiAgICBzZXAgPSAiXyIpDQpkID0gIDExMCAgICAgICAgICAgICANCmNvbmZpZ19wYXJhbSA8LSBhcy52ZWN0b3Iob3V0ZXIoYygiXyIsICJjZW50ZXIiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJfIiwgInNjYWxlIiksIEZVTj1wYXN0ZSkpICU+JQ0KIHJlcChjKGQsZCxkLGQpKQ0KDQpsaXN0X3BjYV9kZiAlPiUNCiAgbWFwX2Rmcih+IHRpZHkoLiwgbWF0cml4PSJwY3MiKSkgJT4lDQogIG11dGF0ZShQYXJhbWV0ZXIgPSBjb25maWdfcGFyYW0pIC0+IGRmX3BjYV9jX3MNCiANCmRmX3BjYV9jX3MgICU+JQ0KICBmaWx0ZXIoUEMgPCA1KSAlPiUNCiAgZ2dwbG90KCkgKw0KICBhZXMoeD1QQywgeSA9IHBlcmNlbnQsIGZpbGwgPSBQYXJhbWV0ZXIpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHRoZW1lX2J3KCkgKw0KICBsYWJzKHRpdGxlID0gIkxpZmVfdGFibGUgOiBzaGFyZSBvZiBpbmVydGlhIHBlciBQQyIsDQogICAgICAgc3VidGl0bGUgPSAiQ2VudGVyaW5nLCBzY2FsaW5nIG9yIG5vdCIpDQpgYGANCg0KTGVzIGLDonRvbnMgc29udCBwcm9wb3J0aW9ubmVscyBhdXggY2FycsOpcyBkZXMgdmFsZXVycyBzaW5ndWxpw6hyZXMgbm9ybWFsaXPDqWVzIHBhciBsYSBzb21tZSBkZXMgY2FycsOpcyBkZXMgdmFsZXVycyBzaW5ndWxpw6hyZXMuDQpTaSBsJ29uIG5lIGNlbnRyZSBwYXMgbm9zIGRvbm7DqWVzLCBub3MgZG9ubsOpZXMgc2Vyb250IHRyb3AgcsOpZHVpdGVzLCBpbCBmYXV0IGFsb3JzIGxlcyBjZW50cmVyLiBFbiBlZmZldCwgcG91ciBsYSBwcmVtacOocmUgY29tcG9zYW50ZSBwcmluY2lwYWxlLCBsZXMgYsOidG9ucyByb3NlIGV0IHZlcnQgcmVwcsOpc2VudGVudCBwcmF0aXF1ZW1lbnQgMTAwICUgZXQgcGx1cyBkZSA4NSAlIGRlIGxhIHBhcnQgZGUgbCdpbmVydGllIHRvdGFsZSBleHBsaXF1w6llIHBhciBsYSBwcmVtacOocmUgY29tcG9zYW50ZS4gT24gcGV1dCBhbG9ycyBwcm9qZXRlciBub3MgZG9ubsOpZXMgc3VyIHVuZSBkaW1lbnNpb24gZXQgb24gcGVyZHJhIHRyw6hzIHBldSBkJ2luZm9ybWF0aW9uLiBDZXBlbmRhbnQsIGVuIGZhaXNhbnQgY2VsYSwgbm91cyByw6lkdWlzb25zIGJlYXVjb3VwIHRyb3Agbm9zIGRvbm7DqWVzLg0KDQpPbiBjb25zdGF0ZSBxdWUgc2kgbCdvbiBjZW50cmUgZXQgcXVlIGwnb24gbm9ybWFsaXNlIG91IG5vbiBub3MgZG9ubsOpZXMsIG9uIHLDqWN1cMOocmUgcHJhdGlxdWVtZW50IDc1ICUgZCdpbmZvcm1hdGlvbnMgc3VyIGxhIHByZW1pw6hyZSBjb21wb3NhbnRlIHByaW5jaXBhbGUgZXQgb24gcsOpY3Vww6hyZSDDqWdhbGVtZW50IGRlcyBpbmZvcm1hdGlvbnMgc3VyIGxhIHNlY29uZGUgY29tcG9zYW50ZSBwcmluY2lwYWxlLg0KDQpJbCBmYXV0IGRvbmMgb2JsaWdhdG9pcmVtZW50IGNlbnRyZXIgbm9zIGRvbm7DqWVzLCBxdWFudCDDoCBsYSBub3JtYWxpc2F0aW9uLCBlbGxlIHJlc3RlIG9wdGlvbm5lbGxlLg0KDQotIFsgXSBFZmZlY3R1ZXogdW5lIEFDUCBzdXIgbCdlbnNlbWJsZSBkZXMgcGF5cyBldCBkZXMgc2V4ZXMgYXZlYyBsYSBjb21iaW5haXNvbiBkZSBjZW50cmFnZSBldCBkZSBtaXNlIMOgIGwnw6ljaGVsbGUgY2hvaXNpZS4NCg0KYGBge3J9DQojIyMjIyMjIyMgRlJBTkNFDQpjb3VudHJ5IDwtICJGcmFuY2UiDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9GRiA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX0ZGICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfRkYpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9GRiA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX0ZGLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX0ZGLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQpjb3VudHJ5IDwtICJGcmFuY2UiDQpnZW5kZXIgPC0gIk1hbGUiDQp5ZWFyIDwtIHNlcSgxOTQ4LDIwMTAsMSkNCg0KbGlmZV90YWJsZV9wY2FfRk0gPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9GTSAlPiUgIHNlbGVjdChZZWFyKQ0KbGlmZV9iaXMgPSBjYmluZChsaWZlX3llYXIsIGxpZmVfdGFibGVfcGNhX0ZNKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2FfRk0gPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCnJlc19GTS5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYV9GTSxzY2FsZT1ULGNlbnRlciA9IFQpDQoNCiMjIyMjIyMjIyBJVEFMWQ0KDQpjb3VudHJ5IDwtICJJdGFseSINCmdlbmRlciA8LSAiRmVtYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX0lGIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfSUYgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9JRikNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX0lGIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfSUYuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfSUYsc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQpjb3VudHJ5IDwtICJJdGFseSINCmdlbmRlciA8LSAiTWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9JTSA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX0lNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfSU0pDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9JTSA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX0lNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX0lNLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQojIyMjIyMjIyMgU1BBSU4NCg0KY291bnRyeSA8LSAiU3BhaW4iDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9TRiA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1NGICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfU0YpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9TRiA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1NGLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1NGLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQpjb3VudHJ5IDwtICJTcGFpbiINCmdlbmRlciA8LSAiTWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9TTSA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1NNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfU00pDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9TTSA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1NNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1NNLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KIyMjIyMjIyMjIEVuZ2xhbmQgJiBXYWxlcw0KDQpjb3VudHJ5IDwtICJFbmdsYW5kICYgV2FsZXMiDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9FV0YgPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9FV0YgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9FV0YpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9FV0YgPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCnJlc19FV0YuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfRVdGLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQpjb3VudHJ5IDwtICJFbmdsYW5kICYgV2FsZXMiDQpnZW5kZXIgPC0gIk1hbGUiDQp5ZWFyIDwtIHNlcSgxOTQ4LDIwMTAsMSkNCg0KbGlmZV90YWJsZV9wY2FfRVdNIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfRVdNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfRVdNKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2FfRVdNIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfRVdNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX0VXTSxzY2FsZT1ULGNlbnRlciA9IFQpDQoNCg0KIyMjIyMjIyMjIFN3ZWRlbg0KDQpjb3VudHJ5IDwtICJTd2VkZW4iDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9TV0YgPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9TV0YgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9TV0YpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9TV0YgPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCiNyZXNfU1dGLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1NXRixzY2FsZT1ULGNlbnRlciA9IFQpDQoNCg0KY291bnRyeSA8LSAiU3dlZGVuIg0KZ2VuZGVyIDwtICJNYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX1NXTSA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1NXTSAlPiUgIHNlbGVjdChZZWFyKQ0KbGlmZV9iaXMgPSBjYmluZChsaWZlX3llYXIsIGxpZmVfdGFibGVfcGNhX1NXTSkNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX1NXTSA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1NXTS5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYV9TV00sc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQoNCiMjIyMjIyMjIyBVU0ENCg0KY291bnRyeSA8LSAiVVNBIg0KZ2VuZGVyIDwtICJGZW1hbGUiDQp5ZWFyIDwtIHNlcSgxOTQ4LDIwMTAsMSkNCg0KbGlmZV90YWJsZV9wY2FfVVNBRiA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1VTQUYgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9VU0FGKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2FfVVNBRiA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1VTQUYuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfVVNBRixzY2FsZT1ULGNlbnRlciA9IFQpDQoNCg0KY291bnRyeSA8LSAiVVNBIg0KZ2VuZGVyIDwtICJNYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX05NIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfTk0gJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9OTSkNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX05NIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfTk0uYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfTk0sc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQoNCiMjIyMjIyMjIyBORVRIRVJMQU5Ecw0KDQpjb3VudHJ5IDwtICJOZXRoZXJsYW5kcyINCmdlbmRlciA8LSAiRmVtYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX05GIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfTkYgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9ORikNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX05GIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfTkYuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfTkYsc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQoNCmNvdW50cnkgPC0gIk5ldGhlcmxhbmRzIg0KZ2VuZGVyIDwtICJNYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX1VTQU0gPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9VU0FNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfVVNBTSkNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX1VTQU0gPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCnJlc19VU0FNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1VTQU0sc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQpgYGANCg0KLSBbIF0gQ29tYmluZXogbGVzIGBzY3JlZXBsb3RzYCBwb3VyIGRpZmbDqXJlbnRzIHBheXMgKHBvdXIgY2hhcXVlIHNleGUpLiBDb21tZW50YWlyZQ0KDQoNCg0KIyBNb2TDqGxlIExlZS1DYXJ0ZXIgcG91ciBsYSBtb3J0YWxpdMOpIGF1eCDDiXRhdHMtVW5pcw0KDQpBdSBjb3VycyBkdSBzacOoY2xlIGRlcm5pZXIsIGF1eCDDiXRhdHMtVW5pcyBldCBlbiBFdXJvcGUgb2NjaWRlbnRhbGUsDQpsZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgw6AgdG91cyBsZXMgw6JnZXMgb250IHByw6lzZW50w6kgdW5lIHRlbmRhbmNlIGfDqW7DqXJhbGUgw6AgbGEgYmFpc3NlLg0KQ2V0dGUgdGVuZGFuY2Ugw6AgbGEgYmFpc3NlIG4nYSBwYXMgdG91am91cnMgw6l0w6kgaG9tb2fDqG5lIGVudHJlIGxlcyDDomdlcy4NCg0KTGUgbW9kw6hsZSBkZSBMZWUtQ2FydGVyIGEgw6l0w6kgY29uw6d1IHBvdXIgbW9kw6lsaXNlciBldCBwcsOpdm9pciBsJ8Opdm9sdXRpb24gZHUgcXVvdGllbnQgbG9nLW1vcnRhbGl0w6kuDQpsJ8Opdm9sdXRpb24gZGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGxvZ2FyaXRobWlxdWUgcG91ciBsZXMgw4l0YXRzLVVuaXMgYXUgY291cnMgZHUgWFhlIHNpw6hjbGUuDQoNClNvaXQgJEFfe3gsdH0kIGxlIGxvZ2FyaXRobWUgZHUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSDDoCBsJ8OiZ2UgJHgkIHBlbmRhbnQgbCdhbm7DqWUgJHRcaW4gVCQuDQpwb3VyIHVuZSBwb3B1bGF0aW9uIGRvbm7DqWUgKGTDqWZpbmllIHBhciBsZSBzZXhlIGV0IGxlIHBheXMpLg0KDQpMZSBtb2TDqGxlIGRlIExlZS1DYXJ0ZXIgc3VwcG9zZSBxdWUgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGxvZ2FyaXRobWlxdWVzIG9ic2VydsOpcw0Kc29udCDDqWNoYW50aWxsb25uw6lzIHNlbG9uIGxlIG1vZMOobGUgc3VpdmFudA0KXFsNCkFfe3gsdH0gXHNpbV97XHRleHR7aW5kw6lwZW5kYW50fX0gYV94ICsgYl94IFxrYXBwYV90ICsgXGVwc2lsb25fe3gsdH0NClxdDQpvw7kgJChhX3gpX3gsIChiX3gpX3gkIGV0ICQoXGthcHBhX3QpX3QkIHNvbnQgZGVzIHZlY3RldXJzIGluY29ubnVzIHF1aSBzYXRpc2ZvbnQNClxbDQphX3ggPSBcZnJhY3sxfXt8VHx9XHN1bV97dCBcaW4gVH0gQV97eCx0fVxxcXVhZCBcc3VtX3t0XGluIFR9IFxrYXBwYV90ID0gMCBccXF1YWQgXHN1bV97eH0gYl94XjIgPTENClxdDQpldCAkXGVwc2lsb25fe3gsdH0kIHNvbnQgZGVzIHZhcmlhYmxlcyBhbMOpYXRvaXJlcyBpLmkuZC4gZ2F1c3NpZW5uZXMuDQoNCg0KIyMgRG9ubsOpZXMgVVMNCg0KDQotIFsgXSBBanVzdGV6IHVuIG1vZMOobGUgTGVlLUNhcnRlciBzdXIgbGVzIGRvbm7DqWVzIGFtw6lyaWNhaW5lcyAocG91ciBsZXMgZG9ubsOpZXMgbWFzY3VsaW5lcyBldCBmw6ltaW5pbmVzKSBlbiB2b3VzIGVudHJhw65uYW50IHN1ciBsZXMgYW5uw6llcyBgMTkzM2AganVzcXUnw6AgYDE5OTVgLg0KLSBbIF0gQ29tcGFyZXogbCdhanVzdGVtZW50IGZvdXJuaSBwYXIgbGUgbW9kw6hsZSBkZSBMZWUtQ2FydGVyIGF2ZWMgbCdhanVzdGVtZW50IGZvdXJuaSBwYXIgdW4gbW9kw6hsZSBTVkQgdHJvbnF1w6kgZGUgcmFuZyAkMiQuDQotIFsgXSBDb21wYXJleiBsZXMgdmVjdGV1cnMgYXZlYyAkKGFfeClfeCwgKGJfeClfeCQgZXQgJChca2FwcGFfdClfdCQgYXZlYyBsZXMgdmVjdGV1cnMgc2luZ3VsaWVycyBhcHByb3ByacOpcy4NCi0gWyBdIFV0aWxpc2V6IGxlIG1vZMOobGUgZGUgTGVlLUNhcnRlciBwb3VyIHByw6lkaXJlIGxlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqSBwb3VyIGxlcyBhbm7DqWVzIDIwMDAkIMOgIDIwMTUkLg0KDQpgYGB7cn0NCmEzM185NSA9IHNlcSgxOTMzLDE5OTUsMSkNCg0KbGlmZV9jYXJ0IDwtIGxpZmVfdGFibGUNCmxpZmVfY2FydCA8LSBzZWxlY3QobGlmZV9jYXJ0LEFnZSxDb3VudHJ5LEdlbmRlcixZZWFyLHF4KSAlPiUNCiAgZmlsdGVyKGxpZmVfY2FydCRZZWFyICVpbiUgYTMzXzk1LCBsaWZlX2NhcnQkQ291bnRyeSA9PSAiVVNBIikNCg0KDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpDQpsaWZlX2NhcnRfZiA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiRmVtYWxlIikNCg0KbGlmZV9jYXJ0X21bLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X21bLDNdIDwtIGxvZyhsaWZlX2NhcnRfbVssM10pDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnRfbSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFllYXIsdmFsdWVzX2Zyb20gPSBxeCkNCg0KDQpsaWZlX2NhcnRfZlssYygiR2VuZGVyIiwiQ291bnRyeSIpXSA8LSBsaXN0KE5VTEwpDQpsaWZlX2NhcnRfZlssM10gPC0gbG9nKGxpZmVfY2FydF9mWywzXSkNCmxpZmVfY2FydF9mIDwtIGxpZmVfY2FydF9mICU+JQ0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWWVhcix2YWx1ZXNfZnJvbSA9IHF4KQ0KDQojbGlmZV9jYXJ0X20NCg0KYW0gPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYW1baV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X21baSwyOjY0XSkNCn0NCkEgPC0gbGlmZV9jYXJ0X21bLTFdIC0gYW0NCkEgPC0gdChBKQ0KY29sbmFtZXMoQSkgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQSkNCnNpbmdtIDwtIHNxcnQoZGVjJGRbMV0pDQpibSA8LSBkZWMkdlssMV0NCmttIDwtIC1kZWMkdVssMV0qc2luZ20NCg0KYWYgPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYWZbaV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X2ZbaSwyOjY0XSkNCn0NCkIgPC0gbGlmZV9jYXJ0X2ZbLTFdIC0gYWYNCkIgPC0gdChCKQ0KY29sbmFtZXMoQikgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQikNCnNpbmdmIDwtIHNxcnQoZGVjJGRbMV0pDQpiZiA8LSBkZWMkdlssMV0NCmtmIDwtIC1kZWMkdVssMV0qc2luZ2YNCg0KdHJlbmQxIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5MzM6MTk5NSxrYXBwYSA9IGttLEdlbmRlciA9ICJNYWxlIixjb3VyYmUgPSAiMTkzMy0xOTk1IikNCnRyZW5kMiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTMzOjE5OTUsa2FwcGEgPSBrZixHZW5kZXIgPSAiRmVtYWxlIixjb3VyYmUgPSIxOTMzLTE5OTUiKQ0KdHJlbmQzIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IDAsR2VuZGVyID0iTWFsZSIsY291cmJlID0gIjE5OTYtMjAxNSIpDQp0cmVuZDQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1LGthcHBhID0gMCxHZW5kZXIgPSJGZW1hbGUiLGNvdXJiZSA9ICIxOTk2LTIwMTUiKQ0KDQpBMjIgPC0gbGlmZV9jYXJ0ICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpICU+JQ0KICBzZWxlY3QoLWMoR2VuZGVyLENvdW50cnkpKSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IEFnZSx2YWx1ZXNfZnJvbSA9IHF4KSAlPiUNCiAgc2VsZWN0KC1ZZWFyKSANCkEyMiA8LSBsb2coQTIyKQ0KDQpkZWMyMiA8LSBzdmQoQTIyLDIsMikNCg0KDQojbG0odHJlbmQxJGthcHBhfnRyZW5kMSRZZWFyKQ0KZm9yKGkgaW4gMTpucm93KHRyZW5kMykpew0KICB0cmVuZDNbaSwyXSA9IHRyZW5kM1tpLDFdKi0wLjAzMTY0KzYyLjEzMjIwDQp9DQoNCg0KI2xtKHRyZW5kMiRrYXBwYX50cmVuZDIkWWVhcikNCmZvcihpIGluIDE6bnJvdyh0cmVuZDQpKXsNCiAgdHJlbmQ0W2ksMl0gPSB0cmVuZDRbaSwxXSotMC4wMzc0NSs3My41NDgxMA0KfQ0KDQp0cmVuZCA8LSByYmluZCh0cmVuZDEsdHJlbmQyLHRyZW5kMyx0cmVuZDQpDQoNCihnZ3Bsb3QodHJlbmQsYWVzKFllYXIsa2FwcGEpKSANCiAgKyBnZW9tX2xpbmUoYWVzKGNvbG9yID0gY291cmJlLCBncm91cD1HZW5kZXIpKSANCiAgKyBnZ3RpdGxlKCJDb2VmZmljaWVudCBkZSBtb3J0YWxpdMOpIHBvdXIgbGVzIGFubsOpZXMgMTkzMyDDoCAxOTk1IGV0IFxuIHByw6lkaWN0aW9uIGRlIDE5OTYgw6AgMjAxNSIpIA0KICArIGZhY2V0X2dyaWQoR2VuZGVyfi4pIA0KICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZC5pdGFsaWMiKSkNCiAgKyB0aGVtZV9idygpKSAgJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID00NTAsIHdpZHRoPTgwMCkNCg0KYGBgDQoNCi0gWyBdIFRyYWNleiBsZXMgcHLDqWRpY3Rpb25zIGV0IGxlcyBvYnNlcnZhdGlvbnMgcG91ciBsZXMgYW5uw6llcyAyMDAwLCAyMDA1LCAyMDEwIGV0IDIwMTUuDQoNCmBgYHtyfQ0KYTk2XzE1ID0gc2VxKDE5OTYsMjAxNSwxKQ0KDQpsaWZlX2NhcnQyIDwtIGxpZmVfdGFibGUNCmxpZmVfY2FydDIgPC0gc2VsZWN0KGxpZmVfY2FydDIsQWdlLENvdW50cnksR2VuZGVyLFllYXIscXgpICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0MiRZZWFyICVpbiUgYTk2XzE1LCBsaWZlX2NhcnQyJENvdW50cnkgPT0gIlVTQSIpDQoNCg0KbGlmZV9jYXJ0X20yIDwtIGxpZmVfY2FydDIgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0MiRHZW5kZXIgPT0gIk1hbGUiKQ0KbGlmZV9jYXJ0X2YyIDwtIGxpZmVfY2FydDIgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0MiRHZW5kZXIgPT0gIkZlbWFsZSIpDQoNCmxpZmVfY2FydF9tMlssYygiR2VuZGVyIiwiQ291bnRyeSIpXSA8LSBsaXN0KE5VTEwpDQpsaWZlX2NhcnRfbTJbLDNdIDwtIGxvZyhsaWZlX2NhcnRfbTJbLDNdKQ0KbGlmZV9jYXJ0X20yIDwtIGxpZmVfY2FydF9tMiAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFllYXIsdmFsdWVzX2Zyb20gPSBxeCkNCg0KDQpsaWZlX2NhcnRfZjJbLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X2YyWywzXSA8LSBsb2cobGlmZV9jYXJ0X2YyWywzXSkNCmxpZmVfY2FydF9mMiA8LSBsaWZlX2NhcnRfZjIgJT4lDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBZZWFyLHZhbHVlc19mcm9tID0gcXgpDQoNCiNsaWZlX2NhcnRfbQ0KDQphbTIgPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYW0yW2ldID0gKDEvMjApICogc3VtKGxpZmVfY2FydF9tMltpLDI6MjFdKQ0KfQ0KQTIgPC0gbGlmZV9jYXJ0X20yWy0xXSAtIGFtMg0KQTIgPC0gdChBMikNCmNvbG5hbWVzKEEyKSA9IHNlcSgxOjExMCktMQ0KZGVjMiA8LSBzdmQoQTIpDQpzaW5nbSA8LSBzcXJ0KGRlYzIkZFsxXSkNCmJtMiA8LSBkZWMyJHZbLDFdDQprbTIgPC0gLWRlYzIkdVssMV0qc2luZ20NCg0KYWYyID0gdmVjdG9yKCJudW1lcmljIiwxMTApDQpmb3IoaSBpbiAxOjExMCl7DQogIGFmMltpXSA9ICgxLzIwKSAqIHN1bShsaWZlX2NhcnRfZjJbaSwyOjIxXSkNCn0NCkIyIDwtIGxpZmVfY2FydF9mMlstMV0gLSBhZjINCkIyIDwtIHQoQjIpDQpjb2xuYW1lcyhCMikgPSBzZXEoMToxMTApLTENCmRlYzIgPC0gc3ZkKEIyKQ0Kc2luZ2YgPC0gc3FydChkZWMyJGRbMV0pDQpiZjIgPC0gZGVjMiR2WywxXQ0Ka2YyIDwtIC1kZWMyJHVbLDFdKnNpbmdmDQoNCnRyZW5kM1ssNF0gPSAiUHLDqWRpY3Rpb24iDQp0cmVuZDRbLDRdID0gIlByw6lkaWN0aW9uIg0KdHJlbmQ1IDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IGttMixHZW5kZXIgPSAiTWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCnRyZW5kNiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTk2OjIwMTUsa2FwcGEgPSBrZjIsR2VuZGVyID0gIkZlbWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCg0KDQojcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgcHLDqWRpdHMNCg0KdHR0bSA8LSBleHAodChhbTIgKyBibTIlKiV0KHRyZW5kMyRrYXBwYSkpKQ0KdHR0ZiA8LWV4cCh0KGFmMiArIGJmMiUqJXQodHJlbmQ0JGthcHBhKSkpDQoNCmxpZmVfY2FydHggPC0gc2VsZWN0KGxpZmVfY2FydDIsWWVhcixBZ2UsQ291bnRyeSxHZW5kZXIscXgpICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0MiRZZWFyICVpbiUgYTk2XzE1LCBsaWZlX2NhcnQyJENvdW50cnkgPT0gIlVTQSIpICU+JQ0KICBzZWxlY3QoLWMoQ291bnRyeSkpDQogIA0KICANCmxpZmVfY2FydHg8LWRhdGEuZnJhbWUobGlmZV9jYXJ0eCx0eXBlPSJPYnNlcnZhdGlvbnMiKQ0KDQoNCnllYXJ0dHQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1KQ0KdHR0bSA8LSBjYmluZCh5ZWFydHR0LHR0dG0pDQp0dHRtIDwtIHBpdm90X2xvbmdlcih0dHRtLGNvbHMgPSAtYyhZZWFyKSxuYW1lc190byA9ICJBZ2UiLHZhbHVlc190byA9ICJxeCIpDQp0dHRtPC0gZGF0YS5mcmFtZSh0dHRtLHR5cGU9IlByw6lkaWN0aW9ucyIsIEdlbmRlciA9ICJNYWxlIikNCg0KdHR0ZiA8LSBjYmluZCh5ZWFydHR0LHR0dGYpDQp0dHRmIDwtIHBpdm90X2xvbmdlcih0dHRmLGNvbHMgPSAtYyhZZWFyKSxuYW1lc190byA9ICJBZ2UiLHZhbHVlc190byA9ICJxeCIpDQp0dHRmPC0gZGF0YS5mcmFtZSh0dHRmLHR5cGU9IlByw6lkaWN0aW9ucyIsIEdlbmRlciA9ICJGZW1hbGUiKQ0KDQoNCnR0dCA8LSByYmluZCh0dHRtLHR0dGYsbGlmZV9jYXJ0eCkNCg0KDQoNCnR0dCA8LSB0dHQlPiUNCiAgZmlsdGVyKHR0dCRZZWFyJWluJSBjKDIwMDAsMjAwNSwyMDEwLDIwMTUpKQ0KDQp0dHRbLDJdIDwtIGFzLm51bWVyaWModHR0WywyXSkNCg0KKGdncGxvdCh0dHQsIGFlcyhBZ2UscXgsIGZyYW1lPVllYXIsIGdyb3VwPUdlbmRlcikpDQorZ2VvbV9saW5lKGFlcyhjb2xvcj10eXBlKSkNCiAgK2xhYnModGl0bGU9J0NvbXBhcmFpc29uIGRlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqSBwcsOpZGl0cyBldCBvYnNlcnbDqXMnLCB5PSdRdW90aWVudCBkZSBtb3J0YWxpdMOpJywgeD0nYWdlJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikpDQogICsgZmFjZXRfZ3JpZCh+R2VuZGVyKStzY2FsZV95X2xvZzEwKGxhYmVscz1zY2llbnRpZmljKQ0KICArIHRoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID0gNTAwLCB3aWR0aD03NTApDQoNCmBgYA0KDQojIyBBcHBsaWNhdGlvbiBkdSBtb2TDqGxlIGRlIExlZS1DYXJ0ZXIgw6AgdW4gcGF5cyBldXJvcMOpZW4NCg0KLSBbIF0gQWp1c3RleiB1biBtb2TDqGxlIGRlIExlZS1DYXJ0ZXIgw6AgdW4gcGF5cyBldXJvcMOpZW4uDQotIFsgXSBDb21tZW50YWlyZQ0KLSBbIF0gQ29tcGFyZXogYXZlYyBsYSBTVkQgdHJvbnF1w6llIGRlIHJhbmcgMi4NCi0gWyBdIFV0aWxpc2VyIGxlIG1vZMOobGUgZGUgTGVlLUNhcnRlciBwb3VyIHByw6lkaXJlIGxlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqSBwb3VyIGxlcyBhbm7DqWVzICQyMDAwJCDDoCAkMjAxNSQuDQoNCg0KYGBge3J9DQojTGVlIGNhcnRlciBldXJvcGUNCmEzM185NSA9IHNlcSgxOTMzLDE5OTUsMSkNCg0KbGlmZV9jYXJ0IDwtIGxpZmVfdGFibGUNCmxpZmVfY2FydCA8LSBzZWxlY3QobGlmZV9jYXJ0LEFnZSxDb3VudHJ5LEdlbmRlcixZZWFyLHF4KSAlPiUNCiAgZmlsdGVyKGxpZmVfY2FydCRZZWFyICVpbiUgYTMzXzk1LCBsaWZlX2NhcnQkQ291bnRyeSA9PSAiRnJhbmNlIikNCg0KDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpDQpsaWZlX2NhcnRfZiA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiRmVtYWxlIikNCg0KbGlmZV9jYXJ0X21bLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X21bLDNdIDwtIGxvZyhsaWZlX2NhcnRfbVssM10pDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnRfbSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFllYXIsdmFsdWVzX2Zyb20gPSBxeCkNCg0KDQpsaWZlX2NhcnRfZlssYygiR2VuZGVyIiwiQ291bnRyeSIpXSA8LSBsaXN0KE5VTEwpDQpsaWZlX2NhcnRfZlssM10gPC0gbG9nKGxpZmVfY2FydF9mWywzXSkNCmxpZmVfY2FydF9mIDwtIGxpZmVfY2FydF9mICU+JQ0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWWVhcix2YWx1ZXNfZnJvbSA9IHF4KQ0KDQojbGlmZV9jYXJ0X20NCg0KYW0gPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYW1baV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X21baSwyOjY0XSkNCn0NCkEgPC0gbGlmZV9jYXJ0X21bLTFdIC0gYW0NCkEgPC0gdChBKQ0KY29sbmFtZXMoQSkgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQSkNCnNpbmdtIDwtIHNxcnQoZGVjJGRbMV0pDQpibSA8LSBkZWMkdlssMV0NCmttIDwtIC1kZWMkdVssMV0qc2luZ20NCg0KYWYgPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYWZbaV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X2ZbaSwyOjY0XSkNCn0NCkIgPC0gbGlmZV9jYXJ0X2ZbLTFdIC0gYWYNCkIgPC0gdChCKQ0KY29sbmFtZXMoQikgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQikNCnNpbmdmIDwtIHNxcnQoZGVjJGRbMV0pDQpiZiA8LSBkZWMkdlssMV0NCmtmIDwtIC1kZWMkdVssMV0qc2luZ2YNCg0KdHJlbmQxIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5MzM6MTk5NSxrYXBwYSA9IGttLEdlbmRlciA9ICJNYWxlIixjb3VyYmUgPSAiMTkzMy0xOTk1IikNCnRyZW5kMiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTMzOjE5OTUsa2FwcGEgPSBrZixHZW5kZXIgPSAiRmVtYWxlIixjb3VyYmUgPSIxOTMzLTE5OTUiKQ0KdHJlbmQzIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IDAsR2VuZGVyID0iTWFsZSIsY291cmJlID0gIjE5OTYtMjAxNSIpDQp0cmVuZDQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1LGthcHBhID0gMCxHZW5kZXIgPSJGZW1hbGUiLGNvdXJiZSA9ICIxOTk2LTIwMTUiKQ0KDQpBMjIgPC0gbGlmZV9jYXJ0ICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpICU+JQ0KICBzZWxlY3QoLWMoR2VuZGVyLENvdW50cnkpKSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IEFnZSx2YWx1ZXNfZnJvbSA9IHF4KSAlPiUNCiAgc2VsZWN0KC1ZZWFyKSANCkEyMiA8LSBsb2coQTIyKQ0KDQpkZWMyMiA8LSBzdmQoQTIyLDIsMikNCg0KDQojbG0odHJlbmQxJGthcHBhfnRyZW5kMSRZZWFyKQ0KZm9yKGkgaW4gMTpucm93KHRyZW5kMykpew0KICB0cmVuZDNbaSwyXSA9IHRyZW5kM1tpLDFdKi0wLjAzMTY0KzYyLjEzMjIwDQp9DQoNCg0KI2xtKHRyZW5kMiRrYXBwYX50cmVuZDIkWWVhcikNCmZvcihpIGluIDE6bnJvdyh0cmVuZDQpKXsNCiAgdHJlbmQ0W2ksMl0gPSB0cmVuZDRbaSwxXSotMC4wMzc0NSs3My41NDgxMA0KfQ0KDQp0cmVuZCA8LSByYmluZCh0cmVuZDEsdHJlbmQyLHRyZW5kMyx0cmVuZDQpDQoNCg0KKGdncGxvdCh0cmVuZCxhZXMoWWVhcixrYXBwYSkpIA0KICArIGdlb21fbGluZShhZXMoY29sb3IgPSBjb3VyYmUsIGdyb3VwPUdlbmRlcikpIA0KICArIGdndGl0bGUoIkNvZWZmaWNpZW50IGRlIG1vcnRhbGl0w6kgcG91ciBsZXMgYW5uw6llcyAxOTMzIMOgIDE5OTUgZXQgXG4gcHLDqWRpY3Rpb24gZGUgMTk5NSDDoCAyMDE1IikgDQogICsgZmFjZXRfZ3JpZChHZW5kZXJ+LikgDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpKQ0KICArIHRoZW1lX2J3KCkpICAlPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPTQ1MCwgd2lkdGg9ODAwKQ0KDQpgYGANCg0KLSBbIF0gQ29tbWVudGFpcmUNCg0KTGUgY29lZmZpY2llbnQgZGUgbW9ydGFsaXTDqSBkZSBsYSBmcmFuY2Ugc2VtYmxlIGVuIG1veWVubmUgYWxpZ27DqSBhdmVjIGxlIGNvZWZmaWNpZW50IGRlIG1vcnRhbGl0w6kgb2J0ZW51IHBhciBsZSByZWdyw6lzc2VtZW50IGxpbsOpYWlyZS4gRW4gZWZmZXQsIGNlIGRlcm5pZXIgZXN0IHVuIHByb2xvbmdlbWVudCBkdSBjb2VmZmljaWVudCBkZSBtb3J0YWxpdMOpIDE5MzMgw6AgMTk5NS4NCg0KDQogICBUcmFjZXogbGVzIHByw6lkaWN0aW9ucyBldCBsZXMgb2JzZXJ2YXRpb25zIHBvdXIgbGVzIGFubsOpZXMgJDIwMDAsIDIwMDUsIDIwMTAsIDIwMTUkLg0KDQpgYGB7cn0NCmE5Nl8xNSA9IHNlcSgxOTk2LDIwMTUsMSkNCg0KbGlmZV9jYXJ0MiA8LSBsaWZlX3RhYmxlDQpsaWZlX2NhcnQyIDwtIHNlbGVjdChsaWZlX2NhcnQyLEFnZSxDb3VudHJ5LEdlbmRlcixZZWFyLHF4KSAlPiUNCiAgZmlsdGVyKGxpZmVfY2FydDIkWWVhciAlaW4lIGE5Nl8xNSwgbGlmZV9jYXJ0MiRDb3VudHJ5ID09ICJGcmFuY2UiKQ0KDQoNCmxpZmVfY2FydF9tMiA8LSBsaWZlX2NhcnQyICU+JSANCiAgZmlsdGVyKGxpZmVfY2FydDIkR2VuZGVyID09ICJNYWxlIikNCmxpZmVfY2FydF9mMiA8LSBsaWZlX2NhcnQyICU+JSANCiAgZmlsdGVyKGxpZmVfY2FydDIkR2VuZGVyID09ICJGZW1hbGUiKQ0KDQpsaWZlX2NhcnRfbTJbLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X20yWywzXSA8LSBsb2cobGlmZV9jYXJ0X20yWywzXSkNCmxpZmVfY2FydF9tMiA8LSBsaWZlX2NhcnRfbTIgJT4lDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBZZWFyLHZhbHVlc19mcm9tID0gcXgpDQoNCg0KbGlmZV9jYXJ0X2YyWyxjKCJHZW5kZXIiLCJDb3VudHJ5IildIDwtIGxpc3QoTlVMTCkNCmxpZmVfY2FydF9mMlssM10gPC0gbG9nKGxpZmVfY2FydF9mMlssM10pDQpsaWZlX2NhcnRfZjIgPC0gbGlmZV9jYXJ0X2YyICU+JQ0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWWVhcix2YWx1ZXNfZnJvbSA9IHF4KQ0KDQojbGlmZV9jYXJ0X20NCg0KYW0yID0gdmVjdG9yKCJudW1lcmljIiwxMTApDQpmb3IoaSBpbiAxOjExMCl7DQogIGFtMltpXSA9ICgxLzIwKSAqIHN1bShsaWZlX2NhcnRfbTJbaSwyOjIxXSkNCn0NCkEyIDwtIGxpZmVfY2FydF9tMlstMV0gLSBhbTINCkEyIDwtIHQoQTIpDQpjb2xuYW1lcyhBMikgPSBzZXEoMToxMTApLTENCmRlYzIgPC0gc3ZkKEEyKQ0Kc2luZ20gPC0gc3FydChkZWMyJGRbMV0pDQpibTIgPC0gZGVjMiR2WywxXQ0Ka20yIDwtIC1kZWMyJHVbLDFdKnNpbmdtDQoNCg0KYWYyID0gdmVjdG9yKCJudW1lcmljIiwxMTApDQpmb3IoaSBpbiAxOjExMCl7DQogIGFmMltpXSA9ICgxLzIwKSAqIHN1bShsaWZlX2NhcnRfZjJbaSwyOjIxXSkNCn0NCkIyIDwtIGxpZmVfY2FydF9mMlstMV0gLSBhZjINCkIyIDwtIHQoQjIpDQpjb2xuYW1lcyhCMikgPSBzZXEoMToxMTApLTENCmRlYzIgPC0gc3ZkKEIyKQ0Kc2luZ2YgPC0gc3FydChkZWMyJGRbMV0pDQpiZjIgPC0gZGVjMiR2WywxXQ0Ka2YyIDwtIC1kZWMyJHVbLDFdKnNpbmdmDQoNCnRyZW5kM1ssNF0gPSAiUHLDqWRpY3Rpb24iDQp0cmVuZDRbLDRdID0gIlByw6lkaWN0aW9uIg0KdHJlbmQ1IDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IGttMixHZW5kZXIgPSAiTWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCnRyZW5kNiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTk2OjIwMTUsa2FwcGEgPSBrZjIsR2VuZGVyID0gIkZlbWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCg0KDQojcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgcHLDqWRpdHMNCg0KdHR0bSA8LSBleHAodChhbSArIGJtICUqJSB0KHRyZW5kMyRrYXBwYSkpKQ0KdHR0ZiA8LSBleHAodChhZiArIGJmICUqJSB0KHRyZW5kNCRrYXBwYSkpKQ0KDQoNCmxpZmVfY2FydHggPC0gc2VsZWN0KGxpZmVfY2FydDIsWWVhcixBZ2UsQ291bnRyeSxHZW5kZXIscXgpICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0MiRZZWFyICVpbiUgYTk2XzE1LCBsaWZlX2NhcnQyJENvdW50cnkgPT0gIkZyYW5jZSIpICU+JQ0KICBzZWxlY3QoLWMoQ291bnRyeSkpDQogIA0KICANCmxpZmVfY2FydHg8LWRhdGEuZnJhbWUobGlmZV9jYXJ0eCx0eXBlPSJvYnMiKQ0KDQoNCnllYXJ0dHQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1KQ0KdHR0bSA8LSBjYmluZCh5ZWFydHR0LHR0dG0pDQp0dHRtIDwtIHBpdm90X2xvbmdlcih0dHRtLGNvbHMgPSAtYyhZZWFyKSxuYW1lc190byA9ICJBZ2UiLHZhbHVlc190byA9ICJxeCIpDQp0dHRtPC0gZGF0YS5mcmFtZSh0dHRtLHR5cGU9InByZWRpIiwgR2VuZGVyID0gIk1hbGUiKQ0KDQp0dHRmIDwtIGNiaW5kKHllYXJ0dHQsdHR0ZikNCnR0dGYgPC0gcGl2b3RfbG9uZ2VyKHR0dGYsY29scyA9IC1jKFllYXIpLG5hbWVzX3RvID0gIkFnZSIsdmFsdWVzX3RvID0gInF4IikNCnR0dGY8LSBkYXRhLmZyYW1lKHR0dGYsdHlwZT0icHJlZGkiLCBHZW5kZXIgPSAiRmVtYWxlIikNCg0KDQp0dHQgPC0gcmJpbmQodHR0bSx0dHRmLGxpZmVfY2FydHgpDQoNCg0KDQp0dHQgPC0gdHR0JT4lDQogIGZpbHRlcih0dHQkWWVhciVpbiUgYygyMDAwLDIwMDUsMjAxMCwyMDE1KSkNCg0KdHR0WywyXSA9IGFzLm51bWVyaWModHR0WywyXSkNCg0KKGdncGxvdCh0dHQsIGFlcyhBZ2UscXgsIGZyYW1lPVllYXIsIGdyb3VwPUdlbmRlcikpDQorZ2VvbV9saW5lKGFlcyhjb2xvcj10eXBlKSkNCiAgK2xhYnModGl0bGU9J2NvbXBhcmFpc29uIGRlcyBxeCBvYnNlcnbDqWVzIGV0IGRlcyBxeCBwcsOpZGl0cycsIHk9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6knLCB4PSdhZ2UnKQ0KICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZC5pdGFsaWMiKSkNCiAgKyBmYWNldF9ncmlkKH5HZW5kZXIpK3NjYWxlX3lfbG9nMTAobGFiZWxzPXNjaWVudGlmaWMpDQogICsgdGhlbWVfYncoKSklPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPSA1MDAsIHdpZHRoPTgwMCkNCg0KDQpgYGANCg0KDQojIyBQcsOpZGljdGlvbnMgZGUgbCdlc3DDqXJhbmNlIGRlIHZpZSDDoCBkaWZmw6lyZW50cyDDomdlcw0KDQotIFsgXSBVdGlsaXNlciBsJ2FwcHJveGltYXRpb24gZGUgTGVlLUNhcnRlciBwb3VyIGVzdGltZXIgbGVzIGVzcMOpcmFuY2VzIGRlIHZpZSByw6lzaWR1ZWxsZXMuDQotIFsgXSBDb21wYXJlciBhdmVjIGxlcyBlc3DDqXJhbmNlcyBkZSB2aWUgcsOpc2lkdWVsbGVzIG9ic2VydsOpZXMNCg0KIyBSw6lmw6lyZW5jZXMNCg0KX19UYWJsZXMgZGUgbW9ydGFsaXTDqSBldCBkw6ltb2dyYXBoaWVfXw0KDQotIFtIdW1hbiBNb3J0YWxpdHkgRGF0YWJhc2VdKGh0dHBzOi8vd3d3Lm1vcnRhbGl0eS5vcmcpDQotIFtUYWJsZXMgZGUgbW9ydGFsaXTDqSBmcmFuw6dhaXNlcywgSmFjcXVlcyBWYWxsaW4gZXQgRnJhbmNlIE1lc2zDqV0oaHR0cHM6Ly93d3cubGlmZXRhYmxlLmRlL2RhdGEvRlJBL0ZSQTAwMDAxODA2MTk5N0NZMS5wZGYpDQotIFtNb2RlbGluZyBhbmQgRm9yZWNhc3RpbmcgVS5TLiBNb3J0YWxpdHksIFIuRC5MZWUgYW5kIEwuUi4gQ2FydGVyLCBKQVNBIDE5OTJdKGh0dHBzOi8vd3d3LmpzdG9yLm9yZy9zdGFibGUvcGRmLzIyOTAyMDEucGRmKQ0KLSBbTGVzIGRpbWVuc2lvbnMgZGUgbGEgbW9ydGFsaXTDqSwgUy4gTGVkZXJtYW5uLCBKZWFuIEJyZWFzLCBQb3B1bGF0aW9uLCAxOTU5XShodHRwczovL3d3dy5qc3Rvci5vcmcvc3RhYmxlL3BkZi8xNTI2MDgyLnBkZikNCi0gU2FtdWVsIEguIFByZXN0b24sIFBhdHJpY2sgSGV1dmVsaW5lIGFuZCBNaWNoZWwgR3VpbGxvdCwgX0RlbW9ncmFwaHk6IE1lYXN1cmluZyBhbmQgTW9kZWxpbmcgUG9wdWxhdGlvbiBQcm9jZXNzZXNfLCBPeGZvcmQ6IEJsYWNrd2VsbCBQdWJsaXNoZXJzLCAyMDAxLCB4diArIDI5MSBwcC4NCg0KX19HcmFwaGlxdWVzIGV0IHJhcHBvcnRzX18NCg0KLSBbSW50ZXJhY3RpdmUgd2ViLWJhc2VkIGRhdGEgdmlzdWFsaXphdGlvbiB3aXRoIFIsIHBsb3RseSwgYW5kIHNoaW55XShodHRwczovL3Bsb3RseS1yLmNvbS9pbmRleC5odG1sKQ0KLSBbUiBmb3IgRGF0YSBTY2llbmNlXShodHRwczovL3I0ZHMuaGFkLmNvLm56KQ0KLSBbTGF5ZXJlZCBncmFwaGljc10oaHR0cDovL3ZpdGEuaGFkLmNvLm56L3BhcGVycy9sYXllcmVkLWdyYW1tYXIucGRmKQ0KLSBbUGxvdGx5XShodHRwOi8vcGxvdGx5LmNvbS8pDQoNCl9fVGlkeXZlcnNlX18NCg0KLSBbdGlkeXNlbGVjdF0oaHR0cHM6Ly90aWR5c2VsZWN0LnItbGliLm9yZy9hcnRpY2xlcy90aWR5c2VsZWN0Lmh0bWwpDQotIFtkYnBseXJdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9kYnBseXIvdmlnbmV0dGVzL2RicGx5ci5odG1sKQ0KLSBbZGF0YS50YWJsZV0oaHR0cHM6Ly9naXRodWIuY29tL1JkYXRhdGFibGUvZGF0YS50YWJsZSkNCi0gW0RUXShodHRwczovL3JzdHVkaW8uZ2l0aHViLmlvL0RULykNCg0KX19QQ0EsIFNWRF9fDQoNCi0gW0ZhY3RvTWluZVJdKGh0dHA6Ly9mYWN0b21pbmVyLmZyZWUuZnIvaW5kZXhfZnIuaHRtbCkNCi0gW2FkZTRdKGh0dHA6Ly9wYmlsLnVuaXYtbHlvbjEuZnIvYWRlNC9hY2N1ZWlsLnBocCkNCi0gW0ZhY3RvSW52ZXN0aWdhdGVdKGh0dHA6Ly9mYWN0b21pbmVyLmZyZWUuZnIvcmVwb3J0aW5nL2luZGV4X2ZyLmh0bWwpDQotIFtQQ0EgYW5kIFRpZHl2ZXJzZV0oaHR0cHM6Ly9jbWRsaW5ldGlwcy5jb20vMjAxOS8wNS9ob3ctdG8tZG8tcGNhLWluLXRpZHl2ZXJzZS1mcmFtZXdvcmsvKQ0KLSBbdGlkeXByY29tcF0oaHR0cHM6Ly9icm9vbS50aWR5dmVyc2Uub3JnL3JlZmVyZW5jZS90aWR5LnByY29tcC5odG1sKQ0KDQpfX0TDqW1vZ3JhcGhpZV9fDQoNCi0gW1IgcGFja2FnZSBkZW1vZ3JhcGh5XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZGVtb2dyYXBoeS9kZW1vZ3JhcGh5LnBkZikNCg0K